美文网首页
VirtualApp拆解之二:Activity启动流程

VirtualApp拆解之二:Activity启动流程

作者: alen17 | 来源:发表于2017-06-04 21:12 被阅读0次

    一、第一次启动插件中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等等。

    相关文章

      网友评论

          本文标题:VirtualApp拆解之二:Activity启动流程

          本文链接:https://www.haomeiwen.com/subject/cxjbfxtx.html