一、第一次启动插件中Activity的流程
这是指从九宫格点击第一次进入插件时的Activity启动流程。点此链接可查看高清svg图:startActivityFromLaunch
过程分拆:
1、获取插件启动的launch intent
VirtualCore的getLaunchIntent方法通过VPackageManager调用远程(:x进程)的VPackageManagerService的queryIntentActivities方法查询launch intent。
2、发送启动LoadingActivity的请求
请求参数里包含了要启动插件的包名、第一步获取的launch intent、以及由哪个用户启动的(再次申明,VirtualApp是支持多用户的)
3、在LoadingActivity的onCreate回调里做真正启动插件的工作
这个过程包含了以下几步工作
(1)、对插件做dex优化。
(2)、调用VirtualCore的resolveActivityInfo方法解析ActivityInfo,其内部还是要依赖VPackageManager调用远程(:x)进程的VPackageManagerService的相应方法。
(3)、调用VActivityManager的public int startActivity(Intent intent, ActivityInfo info, IBinder resultTo, Bundle options, String resultWho,intrequestCode,intuserId)方法,其实最终是调用了:x进程的VActivityManagerService的对应方法。
4、ActivityStack处理工作
(1)、ActivityStack会向VActivityManagerService查询可用的Stub(坑),然后调用其performStartProcessLocked方法,该方法内部又是去访问可用进程的StubContentProvider的call方法,传递的methodName为initProcess
(2)、调用VClientImpl的initProcess方法初始化该进程相关信息,如ProcessRecord和插件的vuid,其中vuid的获取参看如下代码:
/**
* Returns the vuid that is composed from the userId and the appId.
*@hide
*/
public static intgetUid(intuserId,intappId) {
if(MU_ENABLED) {
returnuserId *PER_USER_RANGE+ (appId %PER_USER_RANGE);
}else{
returnappId;
}
}
(3)、StubContentProvider的initProcess方法处理完成会返回一个Bundle,其中包含了VClientImpl的Binder对象和插件进程的pid,VActivityManagerService则会从Binder中拿到新插件进程的ApplicationThread对象并记录(为了后续处理插件Service)。
(4)、查询可用的StubActivity(占位坑),新建对应的targetIntent,并将要启动的intent信息填入targetIntent中。
5、Hook工作
(1)、启动targetIntent,会进入hooked StartActivity方法(为什么呢?只可意会),该方法发现这是要启动StubActivity,不进行特殊处理。
(2)、真正的AMS会调用插件进程的ApplicationThread的scheduleLaunchActivity方法,然后交由ActivityThread接管,它会利用注入到H的HCallbackStub解析真正要启动的Activity,并上报给VActivityManagerService。
(3)、代理ActivityThread的默认Instrumentation,重写其callActivityOnCreate方法,在这里hack真正启动起来的Activity,如ContextFixer.fixContext、ActivityFixer.fixActivity等等。
二、从插件中启动同进程的standard模式的Activity的流程
这是指在插件启动后,从插件内的Activity跳转到同进程的另一个Activity的过程。点此链接可查看高清svg图:startActivityStandardInSameProcess
过程分拆:
1、第一次Hook
在插件内启动Activity,会进入hooked StartActivity方法,该方法发现这是要启动插件内部的Activity,将解析对应的ActivityInfo,然后交由VActivityManager的public intstartActivity(Intent intent, ActivityInfo info, IBinder resultTo, Bundle options, String resultWho,intrequestCode,intuserId)方法,当然,其实最终是调用了:x进程的VActivityManagerService的对应方法。
2、ActivityStack处理工作
ActivityStack发现要启动的Activity不需要开启新进程,那么它做的事情仅是查询可用的StubActivity(占位坑),新建对应的targetIntent,并将要启动的intent信息填入targetIntent中。最后,重新调用ActivityManagerNative.getDefault.call()的startActivity方法。注意:这里的ActivityManagerNative.getDefault.call()是已经被hook的对象。
3、第二次Hook
(1)、启动第二步建立的targetIntent,会进入hooked StartActivity方法(为什么呢?只可意会),该方法发现这是要启动StubActivity,不进行特殊处理。
(2)、真正的AMS会调用插件进程的ApplicationThread的scheduleLaunchActivity方法,然后交由ActivityThread接管,它会利用注入到H的HCallbackStub解析真正要启动的Activity,并上报给VActivityManagerService。
(3)、代理ActivityThread的默认Instrumentation,重写其callActivityOnCreate方法,在这里hack真正启动起来的Activity,如ContextFixer.fixContext、ActivityFixer.fixActivity等等。
网友评论