Acivity启动流程
用户在 Launcher程序里点击应用图标时,会通知 ActivityManagerService启动应用的入口 Activity,ActivityManagerService发现这个应用还未启动,则会通知 Zygote进程孵化出应用进程,然后在这个 dalvik应用进程里执行 ActivityThread的 main方法。在该方法里会先准备好 Looper和消息队列,然后调用 attach方法将应用进程绑定到 ActivityManagerService,然后进入 loop循环,不断地读取消息队列里的消息,并分发消息。
//ActivityThread类
public static void main(String[]args){
2.//...
3.Looper.prepareMainLooper();
4.ActivityThread thread=new ActivityThread();
5.thread.attach(false);
6.if(sMainThreadHandler==null){
7.sMainThreadHandler=thread.getHandler();
8.}
9.AsyncTask.init();
10.//...
11.Looper.loop();
12.//...}
在ActivityThread的main方法里调用thread.attach(false);attach方法的主要代码如下所示:
//ActivityThread类
private void attach(booleansystem){
sThreadLocal.set(this);
mSystemThread=system;
if(!system){
//...
IActivityManager mgr=ActivityManagerNative.getDefault();
try{
//调用ActivityManagerService的attachApplication方法
//将ApplicationThread对象绑定至ActivityManagerService,
//这样ActivityManagerService就可以
//通过ApplicationThread代理对象控制应用进程
//调用的是ActivityManagerService的attachApplication13.
mgr.attachApplication(mAppThread);
}catch(RemoteExceptionex){
//Ignore16.}
}else{
//...
}
//...}
ActivityManagerService的attachApplication方法执行attachApplicationLocked(thread,callingPid)进行绑定。
attachApplicationLocked方法有两个重要的函数调用 thread.bindApplication和mMainStack.realStartActivityLocked。thread.bindApplication将应用进程的 ApplicationThread对象绑定到 ActivityManagerService,也就是说获得 ApplicationThread对象的代理对象。mMainStack.realStartActivityLocked通知应用进程启动 Activity
//ActivityManagerService类
private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {
ProcessRecord app;
//...
app.thread = thread;
//...
try {
//...
//thread对象其实是 ActivityThread里 ApplicationThread
//对象在 ActivityManagerService的代理对象,故此执行
//thread.bindApplication,最终会调用 ApplicationThread的 bindApplication方法
//最后会调用 queueOrSendMessage会往 ActivityThread的消息队列发送消息,
//消息的用途是 BIND_APPLICATION这样会在 handler里处理 BIND_APPLICATION消息,
//接着调用 handleBindApplication方法处理绑定消息。
thread.bindApplication(processName, appInfo, providers,
app.instrumentationClass, profileFile, profileFd, profileAutoStop,
app.instrumentationArguments, app.instrumentationWatcher, testMode,
enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked());
//...
}
catch (Exception e) {
//...
}
//...
ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
if (hr != null && normalMode) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid && processName.equals(hr.processName)) {
try {
if (mHeadless) {
Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
// realStartActivity会调用 scheduleLaunchActivity启动 activity
//最终会调用 ApplicationThread的 scheduleLaunchActivity方法。
//调用了 queueOrSendMessage往 ActivityThread的消息队列发送了消息 6.
//,消息的用途是启动 Activity
} else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
//mMainStack.realStartActivityLocked真正启动 activity
didSomething = true;
}
} catch (Exception e) {
//...
}
}
else
{//...}
}//...
Return
true;}
ActivityThread的handler调用handleLaunchActivity处理启动Activity的消息,handleLaunchActivity的主要代码如下所示:
//ActivityThread类
privatevoidhandleLaunchActivity(ActivityClientRecordr,IntentcustomIntent){
//...
Activitya=performLaunchActivity(r,customIntent);
if(a!=null){
//...
handleResumeActivity(r.token,false,r.isForward,
!r.activity.mFinished&&!r.startsNotResumed);
//...
}else{
//...
}}
handleLaunchActivity方法里有两个重要的函数调用,performLaunchActivity和handleResumeActivity,performLaunchActivity会调用
Activity的 onCreate,onStart,onResotreInstanceState方法,handleResumeActivity会调用 Activity的 onResume方法.代码如下:
performLaunchActivity的主要代码如下所示:
//ActivityThread类
private Activity performLaunchActivity(ActivityClientRecordr,IntentcustomIntent){
//...
//会调用Activity的onCreate方法
mInstrumentation.callActivityOnCreate(activity,r.state);
//...
//...
//调用Activity的onStart方法
if(!r.activity.mFinished){
activity.performStart();
r.stopped=false;
}
if(!r.activity.mFinished){
if(r.state!=null){
//会调用Activity的onRestoreInstanceState方法
mInstrumentation.callActivityOnRestoreInstanceState(activity,r.state);
}....}
启动Activity主要涉及到的类:
Activity的管理采用binder机制,管理Activity的接口是IActivityManager.ActivityManagerService实现了Activity管理功能,位于 system_server进程,ActivityManagerProxy对象是 ActivityManagerService在普通应用进程的一个代理对象,应用进程通过
ActivityManagerProxy对象调用 ActivityManagerService提供的功能。应用进程并不会直接创建 ActivityManagerProxy对象,而是通过调用 ActiviyManagerNative类的工具方法 getDefault方法得到 ActivityManagerProxy对象。所以在应用进程里通常这样启动
Activty。
ActivityManagerNative.getDefault().startActivity()
ActivityManagerService也需要主动调用应用进程以控制应用进程并完成指定操作。这样ActivityManagerService也需要应用进程的一个 Binder代理对象,而这个代理对象就是 ApplicationThreadProxy对象。 ActivityManagerService通过 IApplicationThread接口管理应用进程,ApplicationThread类实现了IApplicationThread接口,实现了管理应用的操作,ApplicationThread对象运行在应用进程里。ApplicationThreadProxy对象是ApplicationThread对象在ActivityManagerService线程(ActivityManagerService线程运行在system_server进程)内的代理对象,ActivityManagerService通过ApplicationThreadProxy对象调用ApplicationThread提供的功能,比如让应用进程启动某个Activity。
/**
publicstaticvoidmain(String[]args){
Process.setArgV0("<pre-initialized>");
//创建looper4.Looper.prepareMainLooper();
//会通过thread.attach(false)来初始化应用程序的运行环境
ActivityThreadthread=newActivityThread();
thread.attach(false);
}
在建立消息循环之前,会通过thread.attach(false)来初始化应用程序的运行环境,并建立activityThread和ActivityManagerService之间的桥mAppThread,mAppThread是IApplicationThread的一个实例。
1.RuntimeInit.setApplicationObject(mAppThread.asBinder());
2.finalIActivityManagermgr=ActivityManagerNative.getDefault();
3.try{
4.mgr.attachApplication(mAppThread);
5.}catch(RemoteExceptionex){
6.throwex.rethrowFromSystemServer();
7.}
注意:每个应用程序对应着一个 ActivityThread实例,应用程序由 ActivityThread.main打开消息循环。每个应用程序同时也对应着一个 ApplicationThread对象。该对象是 activityThread和 ActivityManagerService之间的桥梁。在 attach中还做了一件事情,就是通过代理调用 attachApplication,并利用 binder的 transact机制,在ActivityManagerService中建立了 ProcessRecord信息。
ActivityManagerService:
在ActivityManagerService中,也有一个用来管理activity的地方:mHistory栈,这个mHistory栈里存放的是服务端的activity记录HistoryActivity(classHistoryRecordextendsIApplicationToken.Stub)。处于栈顶的就是当前running状态的activity。
从该时序图中可以看出,Activity.startActivity()方法最终是通过代理类和 Binder机制,在ActivityManagerService.startActivity方法中执行的。那么在 ActivityManagerService的 startActivity中,主要做了那些事情?我们来看下里面比较重要的代码段:根据
activity、ProcessRecord等信息创建 HistoryRecord实例 r
1.HistoryRecord r = new HistoryRecord( this, callerApp, callingUid,intent, resolvedType, aInfo, mConfiguration,resultRecord,
resultWho,
requestCode,
componentSpecified);
把 r加入到 mHistory中。
mHistory.add(addPos, r);
activity被加入到 mHistory之后,只是说明在服务端可以找到该 activity记录了,但是在客户端目前还没有该 activity记录。还需要通过 ProcessRecord中的 thread(IApplication)变量,调用它的 scheduleLaunchActivity方法在ActivityThread中创建新的
ActivityRecord记录(之前我们说过,客户端的 activity是用 ActivityRecord记录的,并放在 mActivities中)。
5.app.thread.scheduleLaunchActivity(
new Intent(r.intent), r,System.identityHashCode(r), r.info, r.icicle, results, newIntents,
!andResume,
isNextTransitionForward());
在这个里面主要是根据服务端返回回来的信息创建客户端 activity记录 ActivityRecord.并通过 Handler发送消息到消息队列,进入消息循环。在 ActivityThread.handleMessage()中处理消息。最终在 handleLaunchActivity方法中把 ActivityRecord记录加入到
mActivities(mActivities.put(r.token,r))中,并启动 activity。
总结:1)在客户端和服务端分别有一个管理 activity的地方,服务端是在mHistory中,处于 mHistory栈顶的就是当前处于
running状态的 activity,客户端是在 mActivities中。
2)在 startActivity时,首先会在ActivityManagerService中建立 HistoryRecord,并加入到 mHistory中,然后通过 scheduleLaunchActivity在客户端创建 ActivityRecord记录并加入到 mActivities中。最终在 ActivityThread发起请求,进入消息循环,完成 activity的启动和窗口的管理等。