zoukankan      html  css  js  c++  java
  • andorid jar/库源码解析之HotXposed

    目录:andorid jar/库源码解析 

    HotXposed:

      作用:

        免重启手机,实现Xposed hook更新。(当然app是要重启的)

      栗子:

         入口:

       // 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:

    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);
                    }
                });
            }
        }
    }

      源码解读:

        首先来看入口实现。

        1、通过集成 IXposedHookLoadPackage 实现他的 handleLoadPackage方法来实现他的入口。

        2、首先,确定 HookerDispatcher 在包名下面,然后通过去掉他自身的名称,即是包名,也可以写死包名。

        3、通过包名,得到当前安装模块(即Apk)的,路径,一般是(/data/app/包名-1/2/base.apk).这个路径下面。通过判断文件是否存在,可以知道是1还是2

        4、然后 因为得到了apk的路径,可以通过构造一个 PathClassLoader对象,入参传入apk路径和当前的ClassLoader,来创建一个PathClassLoader对象。(下一步大有用处)

        5、把这个ClassLoader,作为入口,调用Xposed的Hook入口方法,即;用于热更新的部分(这里有点绕,我详细解释一下。)

          5.1、因为xposed,载入是在apk加载的时候,这个时候,上面的源码1.是不会被热更新的。

          5.2、而源码2中,是通过加载apk得到的ClassLoader的调用,因为app安装之后,产生了变化,是可以被热更新到的。

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

      引入:

    implementation 'com.github.githubwing:HotXposed:v1.0.0'
  • 相关阅读:
    odoo 错误 Resource interpreted as Stylesheet but transferred with MIME type application/x-css:
    Android架构师之路-架构到代码的演练
    Android架构师之路-架构师的决策
    EventBus
    Android架构师之路-UML图形思考
    Android架构师之路-oop
    EventBus
    java定义接口监听器详解
    INSTALL_FAILED_NO_MATCHING_ABIS
    android---NDK开发helloworld(jni)
  • 原文地址:https://www.cnblogs.com/Supperlitt/p/13123806.html
Copyright © 2011-2022 走看看