懶人福利:一秒創建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;

關注並且私信小編暗號:免重啟,即可獲取免重啟成品哦。


分享到:


相關文章: