插件化讲解到实战4--启动Activity适配9.0,10.0等版本

插件化讲解到实战1–类加载的解析和双亲委派机制
插件化讲解到实战2–调用插件中的类
插件化讲解到实战3–Hook的源码分析和启动插件的Activity
插件化讲解到实战4–启动Activity适配9.0,10.0等版本
继续上一篇的讲解是基于Android8.0,下面对6.0,7.0,9.0,10.0进行适配:

比对代码发现,6.0,7.0的类名和变量名变了,9.0在拿到message处理的时候,H中LAUNCH_ACTIVITY=100没有了,通过159可以找到,源码如下:

HookUtil.java

import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;

import androidx.annotation.NonNull;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

public class HookUtil {

    private static String TARGET_INTENT = "target_Intent";

    public static void hookAMS() {

        // 动态代理需要替换的是IActivityManager
        try {

            // 目的: 为了获取系统的IActivityManager对象 -- private IActivityManager mInstance;
            // Singleton对象
            // 10

            Field iActivityManagerSingletonField = null;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                Class<?> clazz = Class.forName("android.app.ActivityManager");
                iActivityManagerSingletonField = clazz.getDeclaredField("IActivityManagerSingleton");
            } else {
                Class<?> clazz = Class.forName("android.app.ActivityManagerNative");
                iActivityManagerSingletonField = clazz.getDeclaredField("gDefault");
            }

            iActivityManagerSingletonField.setAccessible(true);
            Object singleton = iActivityManagerSingletonField.get(null);

            // mInstance 对象  ---》 IActivityManager对象
            Class<?> signletonClass = Class.forName("android.util.Singleton");
            Field mInstanceField = signletonClass.getDeclaredField("mInstance");
            mInstanceField.setAccessible(true);
            final Object mInstance = mInstanceField.get(singleton);

            Class<?> iActivityManagerClass = Class.forName("android.app.IActivityManager");
            Object mInstanceProxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                    new Class[]{iActivityManagerClass}, new InvocationHandler() {
                        @Override
                        public Object invoke(Object o, Method method, Object[] objects) throws Throwable {


                            /**
                             * startActivity(whoThread, who.getBasePackageName(), intent,
                             *                         intent.resolveTypeIfNeeded(who.getContentResolver()),
                             *                         token, target != null ? target.mEmbeddedID : null,
                             *                         requestCode, 0, null, options);
                             */

                            if ("startActivity".equals(method.getName())) {
                                // 修改Intent
                                int index = 0;

                                for (int i = 0; i < objects.length; i++) {
                                    if (objects[i] instanceof Intent) {
                                        index = i;
                                        break;
                                    }
                                }
                                // 启动插件的 1 --- 代理 2
                                Intent intent = (Intent) objects[index];

                                // 该成启动代理Intent
                                Intent intentProxy = new Intent();
                                intentProxy.setClassName("com.enjoy.leo_plugin",
                                        "com.enjoy.leo_plugin.ProxyActivity");

                                intentProxy.putExtra(TARGET_INTENT, intent);

                                objects[index] = intentProxy;
                            }


                            // 第一个参数:系统的IActivityManager对象
                            return method.invoke(mInstance, objects);
                        }
                    });
            // 用代理对象替换系统的IActivityManager对象 ---> field
//            mInstanceProxy --> 替换系统的 IActivityManager对象  ---》 反射去实现
            // mInstance = mInstanceProxy
            mInstanceField.set(singleton, mInstanceProxy);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void hookHandler() {

        //系统的Callback对象 --》 mh对象 --》 ActivityThread对象 --- 》
        // private static volatile ActivityThread sCurrentActivityThread;

        try {
            // sCurrentActivityThread
            Class<?> clazz = Class.forName("android.app.ActivityThread");
            Field sCurrentActivityThreadField = clazz.getDeclaredField("sCurrentActivityThread");
            sCurrentActivityThreadField.setAccessible(true);
            Object activityThread = sCurrentActivityThreadField.get(null);

            // mh对象
            Field mHField = clazz.getDeclaredField("mH");
            mHField.setAccessible(true);
            Handler mH = (Handler) mHField.get(activityThread);

            Class<?> handlerClass = Class.forName("android.os.Handler");
            Field mCallbackField = handlerClass.getDeclaredField("mCallback");
            mCallbackField.setAccessible(true);

            Handler.Callback callback = new Handler.Callback() {
                @Override
                public boolean handleMessage(@NonNull Message message) {
                    switch (message.what) {
                        case 100:
                            // 拿到了message
                            // ActivityClientRecord的对象 --- msg.obj
                            try {
                                Field intentField = message.obj.getClass().getDeclaredField("·");
                                intentField.setAccessible(true);
                                //  启动代理 2
                                Intent intentProxy = (Intent) intentField.get(message.obj);
                                // 启动插件的1
                                Intent intent = intentProxy.getParcelableExtra(TARGET_INTENT);
                                if (intent != null) {
                                    intentField.set(message.obj, intent);
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            break;
                        case 159:
                            // ClientTransaction transaction = (ClientTransaction) msg.obj

                            Class<?> transactionClass = message.obj.getClass();
                            // private List<ClientTransactionItem> mActivityCallbacks;
                            try {
                                Field mActivityCallbacksField = transactionClass.getDeclaredField("mActivityCallbacks");
                                mActivityCallbacksField.setAccessible(true);
                                List list = (List) mActivityCallbacksField.get(message.obj);

                                for (int i = 0; i < list.size(); i++) {
                                        // LaunchActivityItem的对象
                                        if (list.get(i).getClass().getName()
                                                .equals("android.app.servertransaction.LaunchActivityItem")) {
                                            Object launchActivityItem = list.get(i);
                                            // Intent
                                            Field mIntentProxyField = launchActivityItem.getClass().getDeclaredField("mIntent");
                                            mIntentProxyField.setAccessible(true);
                                            Intent intentProxy = (Intent) mIntentProxyField.get(launchActivityItem);
                                            // 启动插件的1
                                            Intent intent = intentProxy.getParcelableExtra(TARGET_INTENT);
                                            if (intent != null) {
                                                mIntentProxyField.set(launchActivityItem, intent);
                                            }
                                        }
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                            }


                            break;
                    }
                    return false;
                }
            };

            // 系统的callback = 自己创建的callback
            mCallbackField.set(mH, callback);

        } catch (Exception e) {
            e.printStackTrace();
        }


        // 用我们创建的Callback对象,替换系统的Callback对象
    }


}

Android10的适配可以看下面的文章:

https://blog.csdn.net/u014379448/article/details/106299656

我发现,按照原来的思路,android10已经行不通了,原因如图:
在这里插入图片描述通过反射拿到的instance是null,但是上面链接里的demo是可以的,我回头详细分析。

https://blog.csdn.net/qq_22090073/article/details/104063781

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值