Android-第三方开源框架—插件化原理之Activity插件化(腾讯专家最佳插件化讲解),看这篇文章就行了

本文深入探讨了Android插件化的Activity插件化原理,重点讲解了如何通过Hook Instrumentation方案实现。文章通过示例代码详细阐述了Hook IActivityManager和Hook Handler的方法,解释了如何在不破坏AMS校验的情况下,用占坑Activity替换目标Activity,并在后续过程中还原插件Activity的生命周期。此外,文章还提到了Hook点的选择及其在不同系统版本上的应用,强调了Activity生命周期管理的关键在于Activity和AMS之间的token通信。
摘要由CSDN通过智能技术生成

final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);

final IActivityManager am = IActivityManager.Stub.asInterface(b);

return am;

}

};

同样的,getService方法返回了了IActivityManager类型的对象,并且IActivityManager借助了Singleton类来实现单例,确定了无论是Android7.0还是Android8.0,IActivityManager都是比较好的Hook点。Singleton类如下所示,后面会用到。 frameworks/base/core/java/android/util/Singleton.java

public abstract class Singleton {

private T mInstance;

protected abstract T create();

public final T get() {

synchronized (this) {

if (mInstance == null) {

mInstance = create();

}

return mInstance;

}

}

}

由于Hook需要多次对字段进行反射操作,先写一个字段工具类FieldUtil:

FieldUtil.java

public class FieldUtil {

public static Object getField(Class clazz, Object target, String name) throws Exception {

Field field = clazz.getDeclaredField(name);

field.setAccessible(true);

return field.get(target);

}

public static Field getField(Class clazz, String name) throws Exception{

Field field = clazz.getDeclaredField(name);

field.setAccessible(true);

return field;

}

public static void setField(Class clazz, Object target, String name, Object value) throws Exception {

Field field = clazz.getDeclaredField(name);

field.setAccessible(true);

field.set(target, value);

}

其中setField方法不会马上用到,接着定义替换IActivityManager的代理类IActivityManagerProxy,如下所示。

public class IActivityManagerProxy implements InvocationHandler {

private Object mActivityManager;

private static final String TAG = “IActivityManagerProxy”;

public IActivityManagerProxy(Object activityManager) {

this.mActivityManager = activityManager;

}

@Override

public Object invoke(Object o, Method method, Object[] args) throws Throwable {

if (“startActivity”.equals(method.getName())) {//1

Intent intent = null;

int index = 0;

for (int i = 0; i < args.length; i++) {

if (args[i] instanceof Intent) {

index = i;

break;

}

}

intent = (Intent) args[index];

Intent subIntent = new Intent();//2

String packageName = “com.example.liuwangshu.pluginactivity”;

subIntent.setClassName(packageName,packageName+“.StubActivity”);//3

subIntent.putExtra(HookHelper.TARGET_INTENT, intent);//4

args[index] = subIntent;//5

}

return method.invoke(mActivityManager, args);

}

}

Hook点IActivityManager是一个接口,建议采用动态代理。在注释1处拦截startActivity方法,接着获取参数args中第一个Intent对象,它是原本要启动插件TargetActivity的Intent。注释2、3处新建一个subIntent用来启动的StubActivity,注释4处将这个TargetActivity的Intent保存到subIntent中,便于以后还原TargetActivity。注释5处用subIntent赋值给参数args,这样启动的目标就变为了StubActivity,用来通过AMS的校验。 最后用代理类IActivityManagerProxy来替换IActivityManager,如下所示。

HookHelper.java

public class HookHelper {

public static final String TARGET_INTENT = “target_intent”;

public static void hookAMS() throws Exception {

Object defaultSingleton=null;

if (Build.VERSION.SDK_INT >= 26) {//1

Class<?> activityManageClazz = Class.forName(“android.app.ActivityManager”);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值