Activity启动流程

论坛 期权论坛     
选择匿名的用户   2021-5-30 00:19   520   0
<div id="js_content">
<p>本文分析的源代码基于 android27</p>
<p>Activity的启动流程相当复杂,比如我们在Activity <strong>A </strong>打开Activity <strong>B</strong><strong>。</strong>这一过程开始于<strong>A</strong>.startActivity 经过 Android System 的处理,最终调用 <strong>B</strong> 的生命周期方法结束。</p>
<p style="text-align: center"><img src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-1c8f935bc7ca1e5eb37dfeadef149b08"></p>
<p>上面的过程具体描述的话太过于复杂,我们可以将其拆解成3部分依次突破。</p>
<blockquote>
  <ol><li><p>startActivity --&gt; ActivityManagerService</p></li><li><p>ActivityManagerService --&gt; ApplicationThread</p></li><li><p>ApplicationThread --&gt; Activity</p></li></ol>
</blockquote>
<h2>(一) startActivity --&gt; ActivityManagerService</h2>
<p>ActivityManagerService后续简称 AMS。先放一张时序图:<br></p>
<p style="text-align: center"><img src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-447fc5cbb1870de63dfd047d7bb330ca"></p>
<p style="text-align: left">从Activity的startActivity方法到AMS中间的过程并不复杂,下面看下源码中做了哪些操作:</p>
<p style="text-align: left"><strong>Activity的startActivity</strong></p>
<pre class="blockcode"><code class="language-go">1&#64;Override
2public void startActivity(Intent intent, &#64;Nullable Bundle options) {
3        if (options !&#61; null) {
4            //第二个参数为-1,表示不需要知道Activity启动的结果
5            startActivityForResult(intent, -1, options);
6        } else {
7            startActivityForResult(intent, -1);
8}
</code></pre>
<p>startActivity中调用startActivityForResult</p>
<p><strong>Activity的startActivityForResult</strong></p>
<pre class="blockcode"><code class="language-go"> 1public void startActivityForResult(&#64;RequiresPermission Intent intent, int requestCode, &#64;Nullable Bundle options) {
2        if (mParent &#61;&#61; null) {//mParent表示当前Activity的父类,一般为null
3            options &#61; transferSpringboardActivityOptions(options);
4
5            //调用Instrumentation.execStartActivity(),启动新的Activity。
6            //mMainThread类型为ActivityThread, 在attach()时被回调时被赋值。
7            Instrumentation.ActivityResult ar &#61; mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
8            if (ar !&#61; null) {
9                mMainThread.sendActivityResult(
10                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
11                    ar.getResultData());
12            }
13            if (requestCode &gt;&#61; 0) {
14                mStartedActivity &#61; true;
15            }
16
17            cancelInputsAndStartExitTransition(options);
18        } else {
19            ...
20        }
21}
</code></pre>
<p><strong></strong>startActivityForResult也很简单,调用Instrumentation.execStartActivity方法。剩下的交给Instrumentation类去处理。</p>
<blockquote>
  <ol><li><p><strong>Instrumentation</strong>类主要用来监控应用程序与系统交互</p></li><li><p>红色字体标明的mMainThread是<strong>ActivityThread</strong>类型,<strong>ActivityThread</strong>可以理解为一个进程,在这就是<strong>A</strong>所在的进程</p></li><li><p>通过mMainThread获取一个<strong>ApplicationThread</strong>的引用,这个引用就是用来实现进程间通信的,具体来说就 AMS 所在的系统进程通知应用程序进程进行一系列操作,后面会用到</p></li></ol>
</blockquote>
<p><strong>Instrumentation的execStartActivity</strong></p>
<pre class="blockcode"><code class="language-go"> 1public ActivityResult execStartActivity(
2            Context who, IBinder contextThread, IBinder token, Activity target,
3            Intent intent, int requestCode, Bundle options) {
4
5        //将contextThread转成ApplicationThread.
6        IApplicationThread whoThread &#61; (IApplicationThread) contextThread;     
7        /*
8         * 中间代码省略
9         */
10        try {
11            intent.migrateExtraStreamToClipData();
12            intent.prepareToLeaveProcess(who);
13            //实际上这里是通过AIDL来调用AMS的startActivity方法,下面我们看下ActivityManager.getService()的代码
14            int result &#61; ActivityManager.getService()
15                .startActivity(whoThread, who.getBasePackageName(), intent,
16                        intent.resolveTypeIfNeeded(who.getContentResolver()),
17                        token, target !&#61; null ? target.mEmbeddedID : null,
18                        requestCode, 0, null, options);
19            checkStartActivityResult(result, intent);//检查StartActivity的结果
20        } catch (RemoteException e) {
21            throw new RuntimeException(&#34;Failure from system&#34;, e);
22        }
23        return null;
24}
</code></pre>
<p><strong></strong>熟悉Android Binder机制的同学应该很快就能定位到此处实际调用到了ActivityManagerService的startActivity方法。接下来的工作重心就由<strong>A</strong>进程转移到了AMS所在的系统进程。</p>
<h2>(二) AMS --&gt; ApplicationThread</h2>
<p>接
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP