天天看点

[Android]从Launcher开始启动App流程源码分析

以下内容为原创,欢迎转载,转载请注明

<code>com.android.launcher.Launcher</code>就是我们的Launcher页面了,可以看到Launcher其实也是一个<code>Activity</code>:

既然是<code>Activity</code>,那当然也会有<code>onCreate</code>、<code>onResume</code>等生命周期了,按照逻辑,应该会去加载所有App,以网格的布局显示在页面上,果然,在<code>onResume</code>看到了这个方法:

看方法名就可以猜到这个方法就是用来加载所有App信息的,进入这个方法:

这里调用<code>sModel</code>(<code>LauncherModel</code>类型)的<code>loadUserItems</code>方法去加载数据了,<code>sModel</code>明显属于<code>Model</code>层,进入<code>loadUserItems</code>方法:

然后使用<code>DesktopItemsLoader</code>在<code>mDesktopLoaderThread</code>线程中加载,:

然后我们回到<code>Launcher</code>的<code>onDesktopItemsLoaded</code>方法:

继续进入<code>bindDesktopItems</code>方法:

进入<code>startBindingItems</code>方法:

这里使用了<code>Handler</code>发送消息,进入<code>Handler</code>的<code>handleMessage</code>方法:

接收到消息之后调用<code>bindItems</code>方法:

这里我们只考虑app或者app快捷方式的情况,文件夹和widgets暂时不考虑。app或者app快捷方式实质上都是进入了这个逻辑中,调用<code>createShortcut</code>方法:

这里首先inflater出item的布局,然后设置<code>text</code>和<code>OnClickListener</code>,还有tag,这个tag是<code>ApplicationInfo</code>,里面包含了各种App信息,是从App的<code>AndroidManifest.xml</code>的<code>&lt;application&gt;</code>标签中解析出来的。既然设置了点击事件,显然,点击后应该会打开对应的App才对。所以继续看<code>onClick</code>方法:

点击App就会通过<code>startActivitySafely</code>方法使用刚才设置的tag,也就是<code>ApplicationInfo</code>中的intent进行跳转:

然后我们来看看打开某个app的时候整个流程是怎么走的。接着上面的的<code>startActivity()</code>方法走:

可以看到,不管你是调用了<code>startActivity</code>还是<code>startActivityForResult</code>方法,<code>startActivityForResult</code>方法,并且如果是调用的<code>startActivity</code>,则默认<code>requestCode</code>就是-1,所以如果你想调用<code>startActivityForResult</code>的时候,注意不能把<code>requestCode</code>设置为-1,否则它的效果就跟<code>startActivity</code>一样了,不会再回调<code>onActivityResult</code>!,再看看<code>startActivityForResult</code>的实现:

可以看到,Activity内部是使用<code>mInstrumentation</code>(<code>Instrumentation</code>类型)执行<code>execStartActivity</code>方法来实现<code>Activity</code>跳转的,执行完毕后会返回一个<code>Instrumentation.ActivityResult</code>。

然后查看<code>Instrumentation::execStartActivity</code>:

首先通过<code>ActivityManagerNative.getDefault()</code>获得一个<code>IActivityManager</code>的实现类:

先通过Binder IPC的方式从服务端获取一个<code>Activity Manager</code>,然后通过<code>ActivityManagernative</code>封装成一个代理<code>ActivityManagerProxy</code>对象,然后调用<code>startActivity</code>也是使用了Binder IPC进行与服务器端的通信,(整个Android系统的通信机制使用了大量的Binder IPC,这个以后再专门讨论这个吧),接着,我们进入到了<code>com.android.server.am.ActivityManagerService</code>的<code>startActivity</code>方法:

接下来的调用链:

-&gt; <code>startActivityAsUser</code>

-&gt; <code>startActivityMayWait</code>

-&gt; <code>startActivityLocked</code>

-&gt; <code>startActivityUncheckedLocked</code>

-&gt; <code>targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options)</code>

-&gt; <code>mStackSupervisor.resumeTopActivitiesLocked(this, r, options)</code>

-&gt; <code>resumeTopActivityInnerLocked(prev, options);</code>

-&gt; <code>mStackSupervisor.startSpecificActivityLocked(next, true, true)</code>

<code>startSpecificActivityLocked</code>方法如下:

首先从<code>mService</code>找出对应需要启动Activity的进程(通过进程名字和uid,进程名字可以在<code>AndroidManifest.xml</code>中配置)如果可以获取到,说明这个Activity所属的进程已经存在了,也就是说app已经在运行了,那就会调用<code>realStartActivityLocked</code>,否则,如果该Activity所在的App是第一次启动,则会调用<code>mService.startProcessLocked</code>方法:

这3个重载方法做的事情就是,先根据进程名字调用<code>getProcessRecordLocked()</code>获取<code>ProcessRecord</code>,如果<code>ProcessRecord</code>不存在,则调用<code>newProcessRecordLocked()</code>方法建立一个<code>ProcessRecord</code>,并且新的<code>ProcessRecord</code>绑定了<code>ApplicationInfo</code>,<code>uid</code>等信息,但后进入第三个重载方法,执行新建、启动进程。

再看<code>Process::start</code>的实现:

接下来就是通过<code>Zygote</code>进程<code>fork</code>一个新的进程作为app的进程。这里要需要讲的一个参数是<code>processClass</code>,这个参数表示一个类,它用来作为新创建的进程的主入口,会调用这个类的静态<code>main</code>方法,这个参数在<code>startProcessLocked</code>方法中会被检查重置,如果是null的话,就默认是<code>android.app.ActivityThread</code>。

现在App的进程也创建成功了,就会进入<code>android.app.ActivityThread</code>的静态的<code>main</code>中:

然后创建了一个<code>ActivityThread</code>,说明每当一个新的app进程被创建,都会对应一个新的<code>ActivityThread</code>实例,然后调用它的<code>attach</code>方法:

然后再次通过Binder IPC调用<code>ActivityManagerProxy</code>的<code>attachApplication</code>,传入的<code>ApplicationThread</code>(Binder)参数用于在服务端进行回调通信。最后进入<code>ActivityManagerService::attachApplication</code>,再调用<code>attachApplicationLocked(thread, callingPid)</code>

首先,通过pid获取刚刚创建的进程,然后对app进行一些初始化工作,然后调用<code>bindApplication</code>远程调用客户端<code>ActivityThread::bindApplication</code>,再通过<code>Handler</code>调用到<code>ActivityThread::handleBindApplication</code>方法:

首先,创建一个当前App的<code>Context</code>,然后如果<code>data.instrumentationName != null</code>,则初始化<code>Instrumentation</code>相关的变量,并创建<code>Instrumentation</code>的<code>ApplicationInfo</code>等对象来创建<code>Instrumentation</code>的<code>Context</code>,然后创建<code>Instrumentation</code>对象,并调用它的<code>init</code>方法进行初始化。如果<code>data.instrumentationName == null</code>,则new一个<code>Instrumentation</code>(在一个进程中只会有一个<code>Instrumentation</code>实例)然后创建<code>Application</code>对象,并调用它的<code>onCreate</code>方法,这样<code>Application</code>就会被回调了。

然后我们回到<code>ActivityManagerService::attachApplicationLocked</code>方法,远程执行完<code>thread.bindApplication</code>方法之后,接下来会调用<code>mStackSupervisor.attachApplicationLocked(app)</code>方法:

先通过<code>topRunningActivityLocked</code>从堆栈顶端获取要启动的Activity,然后<code>realStartActivityLocked(hr, app, true, true)</code>:

继续通过Binder IPC远程调用<code>scheduleLaunchActivity</code>方法,然后进入<code>ActivityThread</code>的<code>scheduleLaunchActivity</code>方法中,然后通过<code>Handler</code>进入<code>handleLaunchActivity</code>方法:

先调用<code>performLaunchActivity</code>方法返回一个<code>Activity</code>,然后调用<code>handleResumeActivity</code>方法让该<code>Activity</code>进入<code>onResume</code>状态。所以很显然在<code>performLaunchActivity</code>中肯定是生成了<code>Activity</code>实例,并调用了<code>onCreate</code>方法了,来看下代码:

首先,初始化<code>LoadedApk</code>,然后通过<code>Instrumentation</code>来创建一个<code>Activity</code>实例,通过<code>createBaseContextForActivity</code>方法创建一个<code>Activity Context</code>,调用<code>activity</code>的<code>attach</code>方法,然后依次触发该<code>Activity</code>的<code>onCreate</code>、<code>onRestoreInstanceState</code>、<code>onPostCreate</code>等生命周期方法。

<code>createBaseContextForActivity</code>方法如下:

通过<code>ContextImpl::createActivityContext</code>创建的<code>Context</code>对象,可以发现,不论是<code>System Context/App Context/Activity Context</code>,这些<code>Context</code>都是通过<code>ContextImpl</code>生成的,具体这里再挖个坑先。

再继续进入<code>Activity::attach</code>方法:

上面对<code>Activity</code>与<code>ActivityThread</code>、<code>Instrumentation</code>等进行了绑定,所以说每个<code>Activity</code>都含有一个<code>ActivityThread</code>引用和一个<code>Instrumentation</code>引用,而<code>ActivityThread</code>实例和<code>Instrumentation</code>实例在一个进程中都只有一个实例,因为<code>ActivityThread</code>是在进程被创建成功后,进入<code>ActivityThread</code>的<code>static main()</code>时才会被创建,而<code>Instrumentation</code>则是在<code>ActivityThread</code>被创建后进行<code>attach</code>的之后被创建。

<code>Activity::startActivity</code>

<code>Activity::startActivityForResult</code>

<code>Instrumentation::execStartActivity</code>:

携带参数:

<code>who</code>:from的Context

<code>contextThread</code>:from的<code>ActivityThread</code>的<code>ApplicationThread</code>,<code>ApplicationThread</code>中可以通过Binder IPC提供给服务端回调<code>Activity</code>生命周期等操作(from的主线程)。

<code>mToken</code>:<code>Binder</code>类型,用来标识from的Activity,可能为null。

<code>target</code>:from的Activity(所以是用来接收跳转结果的),如果不是从Activity跳转则为null。

<code>intent</code>:跳转Intent。

<code>requestCode</code>:如果是<code>startActivity</code>,则为-1。

<code>options</code>:额外Bundle数据。

<code>ActivityManagerProxy::startActivity()</code>:

<code>caller</code>:上面的<code>contextThread</code>,from主线程。

<code>callingPackage</code>:from的Context包名。

<code>resolvedType</code>:跳转Intent的MIME类型。

<code>resultTo</code>:上面的<code>token</code>,<code>Binder</code>类型,用来标识from的Activity。

<code>resultWho</code>:from的Activity的mEmbeddedID(唯一标示字符串)

<code>startFlags</code>:默认传入为0。

<code>profilerInfo</code>:默认传入为null。

<code>ActivityManagerService::startActivity()</code>(通过Binder IPC调用):

携带参数跟上面一样。

<code>ActivityManagerService::startActivityAsUser</code>

携带参数包括<code>ActivityManagerService::startActivity()</code>所有的参数,最再加一个:

<code>userId</code>:userId,根据给当前进程分配的Linux UID(这个UID可以用来让上层系统服务进行身份识别和权限检查)得到一个userId(如果不是多用户,则直接返回0)。

<code>ActivityStackSupervisor::startActivityMayWait()</code>

参数:

<code>caller</code>:上面的<code>caller/contextThread</code>,from主线程。

<code>callingUid</code>:调用用户uid。

<code>voiceSession</code>:传null。

<code>voiceInteractor</code>:传null。

<code>resultTo</code>:上面的<code>resultTo/token</code>,<code>Binder</code>类型,用来标识from的Activity。

<code>startFlags</code>:传null。

<code>profilerInfo</code>:传null。

<code>outResult</code>:传null。

<code>config</code>:传null。

<code>options</code>:额外数据。

<code>ignoreTargetSecurity</code>:false。

<code>userId</code>:上面的<code>userId</code>,根据给当前进程分配的Linux UID(这个UID可以用来让上层系统服务进行身份识别和权限检查)得到一个userId(如果不是多用户,则直接返回0)。

<code>iContainer</code>:传null。

<code>inTask</code>:null。

<code>ActivityStackSupervisor::startActivityLocked()</code>:

<code>aInfo</code>:<code>ActivityInfo</code>类型,解析from的Activity的Intent信息。

<code>componentSpecified</code>:是否显示指定了<code>component</code>。

<code>outActivity</code>:传null。

<code>container</code>:上面的<code>iContainer</code>,转型成了<code>ActivityContainer</code>,还是null。

在这个方法中,通过<code>ProcessRecord callerApp = mService.getRecordForAppLocked(caller);</code>获取到之前创建的<code>ProcessRecord</code>,然后从<code>Activity</code>栈中根据<code>resultTo/token</code>获取到对应from Activity的<code>ActivityRecord</code>(sourceRecord),然后__创建将要跳转的Activity的ActivityRecord对象__(<code>Token</code>也是在这个时候生成的)。

<code>ActivityStackSupervisor::startActivityUncheckedLocked()</code>:

<code>r</code>:<code>ActivityRecord</code>类型,就是<code>ActivityStackSupervisor::startActivityLocked()</code>中创建的将要跳转的Activity的ActivityRecord对象。

<code>sourceRecord</code>:就是<code>ActivityStackSupervisor::startActivityLocked()</code>方法获取的from Activity的<code>sourceRecord</code>。

<code>doResume</code>:传true。

这个方法中有大量的代码来处理<code>task/stack</code>等方面的逻辑,以后再仔细深入这个方法。

<code>ActivityStrack::startActivityLocked()</code>:

方法调用者:<code>ActivityStack</code>类型,

<code>targetStack</code>:在<code>ActivityStackSupervisor::startActivityUncheckedLocked()</code>中确定的需要添加到的<code>ActivityStack</code>。

<code>r</code>:<code>ActivityRecord</code>类型,就是<code>ActivityStackSupervisor::startActivityLocked()</code>中创建的跳转的Activity的ActivityRecord对象。

<code>newTask</code>:是否<code>Intent</code>是否设置了<code>Intent.FLAG_ACTIVITY_NEW_TASK</code>。

<code>keepCurTransition</code>:这个具体后面再研究,跟<code>Intent</code>的flag有关。

同样,这个方法中有大量的代码来处理<code>task/stack</code>等方面的逻辑,以后再仔细深入这个方法__(执行完这个方法后,<code>ActivityRecord</code>就会被真正加入到<code>ActivityStack</code>中)__。

<code>ActivityStackSupervisor::resumeTopActivitiesLocked()</code>:

<code>target</code>:<code>ActivityRecord</code>类型,就是<code>ActivityStackSupervisor::startActivityLocked()</code>中创建的跳转的Activity的ActivityRecord对象。

<code>targetOptions</code>:额外数据。

<code>ActivityStack::resumeTopActivityLocked()</code>:

<code>prev</code>:<code>ActivityRecord</code>类型,就是<code>ActivityStackSupervisor::startActivityLocked()</code>中创建的跳转的Activity的ActivityRecord对象。

<code>ActivityStack::resumeTopActivityInnerLocked()</code>:

<code>ActivityStackSupervisor::startSpecificActivityLocked()</code>:

<code>r</code>:最顶部没有处于finishing的Activity,就是刚刚在<code>startActivityLocked</code>中加入的将要跳转的<code>ActivityRecord</code>,通过<code>topRunningActivityLocked(null)</code>查找

<code>andResume</code>:传true

<code>checkConfig</code>:传true

<code>ActivityManagerService::startProcessLocked()</code>:

<code>processName</code>:创建进程的名称,就是<code>ActivityStack::startSpecificActivityLocked()</code>中的<code>r.processName</code>

<code>info</code>:<code>ApplicationInfo</code>,也是<code>r.info.applicaitonInfo</code>,具体可以查看<code>ActivityStackSupervisor::startActivityLocked()</code>中创建<code>ActivityRecord</code>的代码。

<code>knownToBeDead</code>:传true。

<code>intentFlags</code>:传0。

<code>hostingType</code>:传字符串“activity”。

<code>hostingName</code>:<code>ComponentName</code>类型,<code>intent</code>中的<code>Componentname</code>

<code>allowWhileBooting</code>:传false。

<code>isolated</code>:传false

<code>keepIfLarge</code>传true

<code>ActivityManagerService::startProcessLocked()</code>(重载方法):

参数包含上面所有,多了以下几个:

<code>isolatedUid</code>:传0

<code>abiOverride</code>:传null

<code>entryPoint</code>:传null

<code>entryPointArgs</code>传null

<code>crashHandler</code>传null

注意:在这个方法中,会创建新进程的<code>ProcessRecord</code>对象,并绑定<code>ApplicationInfo</code>等信息,这样,启动进程后进行<code>bindApplicaiton</code>的时候就可以根据进程PID获取到所有的<code>ApplicationInfo</code>信息了。

<code>app</code>:<code>ProcessRecord</code>类型,创建的进程。

<code>hostingNameStr</code>:通过<code>hostingName</code>生成的字符串(包名 + "/" + 类的简单类名)

<code>Process.start()</code>

参数(省略部分参数):

<code>processClass</code>:上面的<code>entryPoint</code>,但是并不是null了,而是<code>android.app.ActivityThread</code>,因为在<code>ActivityManagerService::startProcessLocked()</code>中被设置默认值了,它表示一个类,用来作为新创建的进程的主入口,会调用这个类的静态main方法。所以启动完这个进程就会进入<code>ActivityThread</code>的<code>static main()</code>方法。

<code>zygoteArgs</code>:fork zygote进程时的参数。

<code>ActivityThread::main()</code>

<code>ActivityThread::attach()</code>

<code>ActivityManagerProxy::attachApplication()</code>:

<code>mAppThread</code>:<code>ApplicationThread()</code>类型,Binder,用来提供给AMS调用。

<code>ActivityManagerService::attachApplication()</code>:

<code>ActivityManagerService::attachApplicationLocked()</code>:

<code>thread</code>:<code>ApplicationThread()</code>类型,Binder,用来提供给AMS调用。上面的<code>mAppThread</code>。

<code>pid</code>:当前调用的进程PID。

<code>IApplicationThread::bindApplication()</code>:

方法调用调用者:上面的<code>thread/mAppThread</code>,Binder,用来提供给AMS调用。

<code>packageName</code>:用的进程名字<code>processName</code>

<code>info</code>:<code>ApplicationInfo</code>类型,从<code>ProcessRecord</code>中的<code>instrumentationInfo或者info</code>,这个<code>ApplicationInfo</code>是在建立<code>ProcessRecord</code>时就保存了。

<code>ActivityThread::bindApplication()</code>:

参数:同上

<code>ActivityThread::handleBindApplication()</code>:

通过Handler调用。

<code>data</code>:<code>AppBindData</code>类型,里面包含的类型<code>processName</code>,<code>providers</code>,<code>instrumentationName</code>,<code>instrumentationArgs</code>,<code>instrumentationWatcher</code>,<code>instrumentationUiAutomationConnection</code>,<code>config</code>等数据。

<code>ActivityManagerService</code>中的<code>ActivityThread::bindApplication()</code>执行完毕之后

<code>ActivityStackSupervisor::attachApplicationLocked()</code>:

<code>app</code>:新建的进程绑定的<code>ProcessRecord</code>。

<code>ActivityStackSupervisor::realStartActivityLocked()</code>:

<code>r</code>:<code>ActivityRecord</code>类型,topRunningActivityLocked从堆栈顶端获取要启动的Activity。

<code>andResume</code>:传入true

<code>checkConfig</code>:传入true

<code>IApplicationThread::scheduleLaunchActivity()</code>:

参数(部分):

<code>intent</code>:将要启动的<code>ActivityRecord</code>中的<code>intent</code>。

<code>token</code>:将要启动的<code>ActivityRecord</code>中的<code>token</code>。

<code>info</code>:将要启动的<code>ActivityRecord</code>中的<code>ApplicationInfo</code>。

<code>ActivityThread::scheduleLaunchActivity()</code>:

Binder IPC调用,参数与<code>IApplicationThread::scheduleLaunchActivity()</code>相同。

<code>ActivityThread::handleLaunchActivity()</code>:

该方法通过Handler调用,参数同上。

<code>r</code>:<code>ActivityClientRecord</code>类型,在<code>ActivityThread::scheduleLaunchActivity()</code>中封装,包括的数据有<code>token</code>, <code>ident</code>, <code>intent</code>, <code>activityInfo</code>等等,但是<code>LoadedApk</code>是这时根据包名从<code>ActivityThread</code>中弱引用缓存中获取的的。

<code>customIntent</code>:null

<code>ActivityThread::performLaunchActivity()</code>:

参数与<code>ActivityThread::handleLaunchActivity()</code>相同。

<code>Activity::attach()</code>:

<code>context</code>:<code>ActivityThread::performLaunchActivity()</code>中创建的<code>Activity Context</code>。

<code>aThread</code>:<code>ActivityThread</code>类型,主线程,一个进程都共用一个。

<code>token</code>:构建<code>ActivityRecord</code>时生成的<code>token</code>。

<code>application</code>:<code>Application</code>第一次的时候创建一遍。

<code>intent</code>:将要启动的ActivityRecord中的intent。

<code>info</code>:<code>ActivityInfo</code>类型,将要启动的ActivityRecord中的<code>ActivityInfo</code>。

<code>Instrumentation::callActivityOnCreate()</code>:

<code>activity</code>:<code>ActivityThread::performLaunchActivity()</code>中创建的<code>Activity</code>。

<code>Activity::performCreate()</code>

<code>Activity::onCreate()</code>

继续阅读