目录:andorid jar/库源码解析 html
免重启手机,实现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安装以后,产生了变化,是能够被热更新到的。
implementation ''com.github.githubwing:HotXposed:v1.0.0