懒人福利:一秒创建Xposed模版

template_xposed_module.png

recipe.xml.ftl

           

xposed_init.ftl 存储的是 Hook类的入口地址

strings.xml.ftl 存储的是 Xpodse模块的描述

XposedMod.java.ftl 创建后的模版代码,可以根据自己的需求,修改模版里面的代码

AndroidManifest.xml.ftl 主要是Xposed的meta字段

build.gradle.ftl 为空

4.bug修复

由于Xposed会预先加载好jar包,因此,build.gradle中的implements需要修改为provided,才不会出现错误。

具体修改build.gradle.ftl,添加下面依赖:

dependencies { provided 'de.robv.android.xposed:api:82'}

0×02 加入免重启功能

原理分析:原理这里不作多描述,实际上就是通过替换Xposed插件生成的APK,然后通过动态加载的方式来调用,以实现免重启的功能。具体可阅读参考文章。

改进:对上面的AS模版进行改造,以实现免重启。

package ${packageName};import android.app.Application;import android.content.Context;import android.content.pm.PackageManager;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List;import dalvik.system.PathClassLoader;import de.robv.android.xposed.IXposedHookLoadPackage;import de.robv.android.xposed.XC_MethodHook;import de.robv.android.xposed.XposedHelpers;import de.robv.android.xposed.callbacks.XC_LoadPackage;public class HookLoader implements IXposedHookLoadPackage { /** * 当前Xposed模块的包名,方便寻找apk文件 */ private final String modulePackage = "${packageName}"; /** * 宿主程序的包名(允许多个),过滤无意义的包名,防止无意义的apk文件加载 */ private static List hostAppPackages = new ArrayList<>(); /** * 实际hook逻辑处理类 */ private final String handleHookClass = ${xposedModClass}.class.getName(); /** * 实际hook逻辑处理类的入口方法 */ private final String handleHookMethod = "handleLoadPackage"; static { // TODO: Add the package name of application your want to hook! hostAppPackages.add("${hookPackageName}"); } @Override public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { if (hostAppPackages.contains(loadPackageParam.packageName)) { XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { Context context=(Context) param.args[0]; loadPackageParam.classLoader = context.getClassLoader(); invokeHandleHookMethod(context, handleHookClass, handleHookMethod, loadPackageParam); } }); } } /** * 安装app以后,通过动态加载这个apk文件,调用相应的方法 * 从而实现免重启 * @param context context参数 * @param handleHookClass 指定由哪一个类处理相关的hook逻辑 * @param loadPackageParam 传入XC_LoadPackage.LoadPackageParam参数 * @throws Throwable 抛出各种异常,包括具体hook逻辑的异常,寻找apk文件异常,反射加载Class异常等 */ private void invokeHandleHookMethod(Context context, String handleHookClass, String handleHookMethod, XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { String apkPath = context.getPackageManager().getApplicationInfo(this.modulePackage,PackageManager.GET_META_DATA).sourceDir; PathClassLoader pathClassLoader = new PathClassLoader(apkPath, ClassLoader.getSystemClassLoader()); Class> cls = Class.forName(handleHookClass, true, pathClassLoader); Object instance = cls.newInstance(); Method method = cls.getDeclaredMethod(handleHookMethod, XC_LoadPackage.LoadPackageParam.class); method.invoke(instance, loadPackageParam); }}

文章作者是通过区分不同的sdk以实现找到apk的findapk的方法,实际上这里有很简便的方法:通过系统API便可找到对应的apk路径:

一行代码即可搞定

String apkPath = context.getPackageManager().getApplicationInfo(this.modulePackage,PackageManager.GET_META_DATA).sourceDir;

关注并且私信小编暗号:免重启,即可获取免重启成品哦。


分享到:


相關文章: