欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

XPosed基本使用 Activity生命周期拦截

程序员文章站 2022-06-28 13:50:53
文章目录核心类核心类上一篇说到如何集成Xposed框架,接下来就是要实现相关功能,初步了解基本使用核心接口:IXposedHookInitPackageResources–>应用加载完成初始化资源时调用IXposedHookLoadPackage -->加载应用时调用IXposedHookZygoteInit --> 系统启动是加载XposedHelpers -->构造帮助类,辅助通过反射获得实体类,方法,属性并对其进行操作demo场景:为方便测试,本文...

文章目录

核心类

上一篇说到如何集成Xposed框架,接下来就是要实现相关功能,初步了解基本使用

  • 核心接口:
    IXposedHookInitPackageResources–>应用加载完成初始化资源时调用
    IXposedHookLoadPackage -->加载应用时调用
    IXposedHookZygoteInit --> 系统启动是加载

    XposedHelpers -->构造帮助类,辅助通过反射获得实体类,方法,属性并对其进行操作

  • demo场景:
    为方便测试,本文将操作页面集成在一个demo中包名:“com.example.xposedmoudle”,目标对象"MainActivity"

public class HookLoadPackage implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable {
        if (loadPackageParam.packageName.equals("com.example.xposedmoudle")) {
            XposedHelpers.findAndHookMethod("com.example.xposedmoudle.MainActivity", loadPackageParam.classLoader, "onCreate", Bundle.class,
                    new XC_MethodHook() {
                        @Override
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                            super.beforeHookedMethod(param);
                        }

                        @Override
                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                            super.afterHookedMethod(param);
                            //通过hook对象拿到目标对象实体
                            Class c = loadPackageParam.classLoader.loadClass("com.example.xposedmoudle.MainActivity");
                            //通过反射获取textview属性
                            Field fild = c.getDeclaredField("tv");
                            //允许访问私有属性
                            fild.setAccessible(true);
                            //得到私有属性textview
                            TextView tv = (TextView) fild.get(param.thisObject);
                            tv.setText("测试");
                        }
                    });
        }
    }
}

  • IXposedHookInitPackageResources
实现 IXposedHookInitPackageResources接口
    @Override
    public void handleInitPackageResources(XC_InitPackageResources.InitPackageResourcesParam resparam) throws Throwable {
        /**
         * 参数createInstance(String path, XResources origRes)
         * path 路径:在那个apk中加载
         * resparam:设置资源文件
         */
//        if(){}判断目标包名
        XModuleResources modRes = XModuleResources.createInstance(MODULE_PATH, resparam.res);
        resparam.res.addResource(modRes, R.drawable.ic_launcher_foreground);
        resparam.res.addResource(modRes, R.drawable.ic_launcher_background);
    }
  • IXposedHookZygoteInit
@Override
    public void initZygote(StartupParam startupParam) throws Throwable {
        //获取加载apk
        MODULE_PATH = startupParam.modulePath;
    }
  • 实现对activity生命周期的拦截
    通过源码追动可以找到ActivityThread 持有Instrumetation实力,他哦难过Instrumentation进行activity生命周期的调用,思路是自定义一个Instrumentation类,替换掉系统的持有.
public class MyInstrumetation extends Instrumentation {
    private static final boolean DEBUG = false;
    private static final String TAG = "MyInstrumentation";
    private Instrumentation mInstrumentation;
    private Context mContext;
    public MyInstrumetation(Context context) {
        this.mContext = context;
        init();
    }
    private void init() {
        try {
            Class<?> activityThreadClass = null;
            activityThreadClass = Class.forName("android.app.ActivityThread");
            Method currentActivityThreadMethod = activityThreadClass.getMethod("currentActivityThread");
            Object sCurrentActivityThrad = currentActivityThreadMethod.invoke(null);
            //获得ActivityThread实例
            Class<?> asClass = sCurrentActivityThrad.getClass();
            Looper mLooper = (Looper) asClass.getMethod("getLooper").invoke(sCurrentActivityThrad);
            Field mInstumentationField = asClass.getDeclaredField("mInstrumentation");
            mInstumentationField.setAccessible(true);
            mInstrumentation = (Instrumentation) mInstumentationField.get(sCurrentActivityThrad);
            Class<? extends Instrumentation> mInstrumentationClass = mInstrumentation.getClass();
            mInstumentationField.set(sCurrentActivityThrad, this);
        } catch (Exception e) {
            Log.e(TAG, "======" + e.getMessage().toString());
        }
    }
    //重写注意super.callActivityOnPause(activity);不能删掉 可以理解为目标Activity的onPause方法
    //按照代码块执行顺序执行-->限制性log 在执行Activity的onPause
    @Override
    public void callActivityOnPause(Activity activity) {
        Log.e("======", "hook--->");
        super.callActivityOnPause(activity);
    }
}

在使用的位置new 出对象,传入上下文
参考资料:https://bbs.pediy.com/thread-225639.htm
框架还在进一步探索中,欢迎大家交流指正

项目地址

本文地址:https://blog.csdn.net/d773689630/article/details/107861610

相关标签: 技术 android