andorid jar/庫源碼解析之HotXposed

目錄:andorid jar/庫源碼解析 html

HotXposed:

  做用:

    免重啓手機,實現Xposed hook更新。(固然app是要重啓的)git

  栗子:

     入口:github

   // Hook 入口
   public
void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { hook(HookerDispatcher.class, lpparam); } public static void hook(Class clazz, XC_LoadPackage.LoadPackageParam lpparam) throws Exception { String packageName = clazz.getName().replace("." + clazz.getSimpleName(), ""); Log.i(tag, "packageName " + packageName); File apkFile = getApkFile(packageName); Log.i(tag, "apkFile.getAbsolutePath " + apkFile.getAbsolutePath()); if (!apkFile.exists()) { Log.i(tag, "apk file not found"); return; } Log.i(tag, "去掉 xposed 通知"); filterNotify(lpparam); PathClassLoader classLoader = new PathClassLoader(apkFile.getAbsolutePath(), lpparam.getClass().getClassLoader()); Log.i(tag, "classLoader " + classLoader); XposedHelpers.callMethod(classLoader.loadClass(clazz.getName()).newInstance(), "dispatch", lpparam); }

  熱更新的Hook:app

public class HookerDispatcher implements IHookerDispatcher {
    private static String tag = "HotXposed";
    @Override
    public void dispatch(final XC_LoadPackage.LoadPackageParam lpparam) {
        if(!Constants.TARGET_PACKAGE_NAME.equals(lpparam.packageName)){
            return;
        }

        Log.i(tag, "dispatch 被調用 熱更新代碼從這裏開始");
        if (lpparam.packageName.contains(Constants.TARGET_PACKAGE_NAME) && lpparam.processName.equals(lpparam.packageName)) {
            findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(final MethodHookParam param) throws Throwable {
                    final ClassLoader cl = ((Context) param.args[0]).getClassLoader();
                    Log.i(tag, "enter 2 " + lpparam.packageName);
                }
            });
        }
    }
}

  源碼解讀:

    首先來看入口實現。ide

    一、經過集成 IXposedHookLoadPackage 實現他的 handleLoadPackage方法來實現他的入口。spa

    二、首先,肯定 HookerDispatcher 在包名下面,而後經過去掉他自身的名稱,便是包名,也能夠寫死包名。code

    三、經過包名,獲得當前安裝模塊(即Apk)的,路徑,通常是(/data/app/包名-1/2/base.apk).這個路徑下面。經過判斷文件是否存在,能夠知道是1仍是2htm

    四、而後 由於獲得了apk的路徑,能夠經過構造一個 PathClassLoader對象,入參傳入apk路徑和當前的ClassLoader,來建立一個PathClassLoader對象。(下一步大有用處)對象

    五、把這個ClassLoader,做爲入口,調用Xposed的Hook入口方法,即;用於熱更新的部分(這裏有點繞,我詳細解釋一下。)blog

      5.一、由於xposed,載入是在apk加載的時候,這個時候,上面的源碼1.是不會被熱更新的。

      5.二、而源碼2中,是經過加載apk獲得的ClassLoader的調用,由於app安裝以後,產生了變化,是能夠被熱更新到的。

  源碼:https://github.com/githubwing/HotXposed

  引入:

implementation ''com.github.githubwing:HotXposed:v1.0.0
相關文章
相關標籤/搜索