VirtualApk源码分析总结

与RePlugin不同,它进行了Framework层的hook。

ClassLoader:
  • 通过配置,它可以将宿主的ClassLoader中的dexElements数组插入到插件的DexClassLoader的dexElements数组的前面,可以让Dex也能加载宿主中的类。
Resources:
  • 通过配置,可以让宿主的Resources对象访问插件的资源,也可以自己创建插件中的Resources对象,让插件自己加载资源。
四大组件:
  • Activity:
    在Activity启动的时候,它hook了Instrumentation,并重写了execStartActivity方法,将intent中的真实Activtiy临时保存到intent中,替换成坑位Activity(会根据theme和launchMode匹配坑位),启动坑位Activity绕过AMS检测。绕过以后,AMS开始启动Activity,会回调Instrumentation的newActivity方法,重写newActivity方法将真正的Activity从intent取出并通过插件的DexClassLoader加载,然后在callActivityOnCreate中替换Context,Resources等。
  • Service:(与Replugin几乎一样)
    在启动Service的时候,它hook了AMS的代理对象gDefault,也就是ActivityManagerNative,通过动态代理的方式,如果方法名称为“startService”,将Intent中的真实要启动的Service保存,将坑位Service替换。此时会真的将坑位Service启动起来(启动之前会传入一个command),启动起来之后,重写坑位Service的onStartCommand方法,并根据command匹配,匹配到了就通过插件的DexClassLoader加载真正的Service并手动调用生命周期。
  • BroadcastReceiver:
    静态注册的广播,会先将apk中的信息解析出来,拿到所有的静态注册的Receiver信息,并通过插件的DexClassLoader加载插件中对应的Receiver类,通过反射创建对象。然后通过宿主的Context动态注册。
    动态注册的广播,直接交给宿主的Context动态注册。
  • ContentProvider:
    根据传入的uri,判断是否需要拉起坑位Provider,拉起的方式与Replugin不同,它是通过hook了ActivityThread,拿到ActivityThread中的mProviderMap,获取到坑位Provider。调用query方法时,也是通过反射创建插件中的真实provider,主动调用相关方法。

一些区别:

RePlugin支持插件和宿主之间,插件和插件之间的相互调用,资源共享,具体的方式是插件A调用插件B,A会通过反射调用宿主,让宿主去调用插件B。
VirtualApk不支持插件间的调用方式。
插件间资源加载的方式,不能直接使用资源,比如R.drawable.resourceId。
比如插件想要访问宿主中的资源,RePlugin中需要通过pluginName,反射调用宿主中的fetchResources对象,拿到Resources对象后通过getIdentifier获取资源Id。

参考:https://github.com/didi/VirtualAPK/wiki/第三方技术文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值