11.2.5 显示Activity
启动应用程序Activity的第五个阶段的主要功能是显示Activity,其入口点是ActivityStack.realStartActivityLocked方法,该方法在attachApplicationLocked执行完bindApplication方法后开始执行,其主要功能是加载Activity,并执行其生命周期的onCreate、onStart、onResume等方法,最终显示Activity。
1.ActivityStack.realStartActivityLocked
Activity显示阶段的第一步是ActivityStack.realStartActivityLocked,代码如下:
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException{
/*当Activity attach到Application,并且应用进程没有异常状态(crash, ANR)
时,需要通过WindowManagerService冻结屏幕并设置Activity可见/
r.startFreezingScreenLocked(app,0);
mService.mWindowManager.setAppVisibility(r.appToken, true);
……
//在ActivityRecord中记录ProcessRecord,即Activity需要保存其运行进程的信息
r.app=app;
app.waitingToKill=null;
//在ProcessRecord中记录ActivityRecord,一个进程可以运行多个Activity
int idx=app.activities.indexOf(r);
if(idx<0){
app.activities.add(r);
}
mService.updateLruProcessLocked(app, true, true);//更新LRU
try{
//此时已经创建应用程序主线程,这里不为null
if(app.thread==null){
throw new RemoteException();
}
List<ResultInfo>results=null;
List<Intent>newIntents=null;
if(andResume){//本例为true
results=r.results;
newIntents=r.newIntents;
}
if(r.isHomeActivity){//本例为false
mService.mHomeProcess=app;
}
r.sleeping=false;
……
//app.thread即ApplicationThreadProxy,是一个BinderProxy对象
//Launch Activity主要包括onCreate、onStart和onResume
app.thread.scheduleLaunchActivity(new Intent(r.intent),
r.appToken, System.identityHashCode(r),r.info,
new Configuration(mService.mConfiguration),
r.compat, r.icicle, results, newIntents,!andResume,
mService.isNextTransitionForward(),profileFile,
profileFd, profileAutoStop);
……
}catch(RemoteException e){
}
r.launchFailed=false;
……
if(andResume){//true
r.state=ActivityState.RESUMED;
r.stopped=false;
mResumedActivity=r;
r.task.touchActiveTime();
if(mMainStack){
//添加到最近Task列表,默认最大数量为20个
mService.addRecentTaskLocked(r.task);
}
completeResumeLocked(r);//执行onResume后的处理
checkReadyForSleepLocked();
r.icicle=null;
r.haveState=false;
}else{
r.state=ActivityState.STOPPED;
r.stopped=true;
}
if(mMainStack){//系统升级时或第一次启动时需要运行Setup Wizard
mService.startSetupActivityLocked();
}
return true;
}
在启动应用程序Activity过程中,ActivityStack.realStartActivityLocked的主要工作由两个方法完成:ApplicationThreadProxy.scheduleLaunchActivity和ActivityStack.completeResume Locked。其中scheduleLaunchActivity用于在ActivityManagerService所在进程向应用程序主线程的消息循环发送LAUNCH_ACTIVITY消息,进而在应用程序主线程中回调Activity生命周期的onCreate、onStart、onResume等方法显示Activity。onResume方法执行完毕后,需要首先将当前显示Activity所在的Task加入最近Task列表,然后调用completeResumeLocked在ActivityManagerService中进行后续处理。
2.ApplicationThread.scheduleLaunchActivity
显示Activity的第二步是ApplicationThreadProxy.scheduleLaunchActivity,通过Binder通信进而调用ApplicationThread.scheduleLaunchActivity方法,代码如下:
public final class ActivityThread{
……
private class ApplicationThread extends ApplicationThreadNative{
……
public final void scheduleLaunchActivity(……){
//创建应用程序进程中保存的Activity信息,以ActivityClientRecord表示
ActivityClientRecord r=new ActivityClientRecord();
//对应于ActivityManagerService中保存的ActivityRecord的BinderProxy
r.token=token;
r.ident=ident;
r.intent=intent;
r.activityInfo=info;
……
//向应用程序主线程发送LAUNCH_ACTIVITY消息
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}
ApplicationThread. scheduleLaunchActivity首先在应用程序进程中创建ActivityClientRecord,其对应于ActivityManagerService中的ActivityRecord;然后通过queueOrSendMessage方法向应用程序主线程ActivityThread发送LAUNCH_ACTIVITY消息。消息的处理由定义在ActivityThread.H的handleMessage方法完成,代码如下:
public final class ActivityThread{
……
final H mH=new H();
……
private class H extends Handler{
public void handleMessage(Message msg){
switch(msg.what){
case LAUNCH_ACTIVITY:{
ActivityClientRecord r=(ActivityClientRecord)msg.obj;
//获取应用程序Activity的LoadedApk
r.packageInfo=getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
}break;
}
}
应用程序主线程收到LAUNCH_ACTIVITY消息后,会在其消息处理器mH的handleMessage方法中根据消息类型匹配switch代码块的LAUNCH_ACTIVITY分支,在该分支中,首先需要根据要启动的Activity信息,找到其对应的APK文件信息(LoadedApk),然后调用handleLaunchActivity进一步处理Activity的启动过程。
以上处理过程的主要流程如图11-4所示。
图 11-4 scheduleLaunchActivity方法执行流程
3.ActivityThread.handleLaunchActivity
显示Activity的第三步是ActivityThread.handleLaunchActivity,代码如下:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent){
unscheduleGcIdler();//暂停调度Idler状态的GC消息处理,见第7章
……
//本例为com.android.settings.Settings
Activity a=performLaunchActivity(r, customIntent);
if(a!=null){
……
handleResumeActivity(r.token, false, r.isForward);
if(!r.activity.mFinished&&r.startsNotResumed){
……
}
}else{
try{//Activity启动失败,直接销毁
ActivityManagerNative.getDefault().
finishActivity(r.token, Activity.RESULT_CANCELED, null);
}catch(RemoteException ex){
//Ignore
}
}
}
handleLaunchActivity将启动Activity的过程分为Launch阶段和Resume阶段,这两个阶段分别由performLaunchActivity和handleResumeActivity完成,如果Activity启动失败,则需要调用finishActivity予以销毁。
4.ActivityThread.performLaunchActivity
显示Activity的第四步是ActivityThread.performLaunchActivity,代码如下:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent){
ActivityInfo aInfo=r.activityInfo;//获取Activity信息
……
ComponentName component=r.intent.getComponent();
……
Activity activity=null;
try{
java.lang.ClassLoader cl=r.packageInfo.getClassLoader();
/通过Java反射机制加载并创建Activity对象,本例中创建com.android.settings.Settings/
activity=mInstrumentation.newActivity(
cl, component.getClassName(),r.intent);
……
}catch(Exception e){
}
try{
/*app中存储要启动的应用程序包名、Activity名、APK文件名等信息,本例
*中主要包含以下信息com.android.settings/com.android.settings
Settingsdir=/system/app/Settings.apk/
Application app=r.packageInfo.makeApplication(false, mInstrumentation);
if(activity!=null){
//创建并初始化Activity对应的Context
ContextImpl appContext=new ContextImpl();
appContext.init(r.packageInfo, r.token, this);
appContext.setOuterContext(activity);
……
//将其他应用程序信息附加(attach)到Activity
activity.attach(appContext, this, getInstrumentation(),r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
……
activity.mCalled=false;
//回调onCreate方法
mInstrumentation.callActivityOnCreate(activity, r.state);
……
r.activity=activity;
r.stopped=true;
if(!r.activity.mFinished){
activity.performStart();//回调onStart方法
r.stopped=false;
}
if(!r.activity.mFinished){
if(r.state!=null){//本例为false
//回调onRestoreInstanceState方法
mInstrumentation.callActivityOnRestoreInstanceState(
activity, r.state);
}
}
if(!r.activity.mFinished){
activity.mCalled=false;
mInstrumentation.callActivityOnPostCreate(activity, r.state);
//回调onPostCreate方法
……
}
}
r.paused=true;
/*在应用程序主线程中记录当前Activity, r.token是ActivityManagerService
中存储的ActivityRecord的BinderProxy/
mActivities.put(r.token, r);
}
……
return activity;
}
performLaunchActivity方法的主要工作是:首先创建Activity对应的Application和Context,并将Activity所需的其他信息附加(attach)到Activity上,然后通过Instrumentation回调Activity生命周期的方法,这些方法包括onCreate、onStart、onRestoreInstanceState(本例未回调该方法)和onPostCreate。通常,应用程序Activity在onCreate中通过setContentView方法设置UI布局和控件,此时Activity便可以显示UI了。
Instrumentation回调Activity生命周期的过程很简单,这里不赘述。将Activity所需的其他信息附加到Activity上由Activity.attach方法完成,代码如下:
final void attach(Context context,……){
attachBaseContext(context);//Activity关联到Context
mFragments.attachActivity(this);//FragmentManager记录当前Activity
//创建Activity对应的Window,对于手机,这个窗口是PhoneWindow
mWindow=PolicyManager.makeNewWindow(this);
mWindow.setCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
……
mUiThread=Thread.currentThread();//当前线程视为UI线程
mMainThread=aThread;//当前ActivityThread视为主线程
mInstrumentation=instr;
mToken=token;//ActivityManagerService中ActivityRecord的BinderProxy
mIdent=ident;
mApplication=application;
mIntent=intent;
mComponent=intent.getComponent();
mActivityInfo=info;
mTitle=title;
mParent=parent;//本例parent为null
mEmbeddedID=id;
mLastNonConfigurationInstances=lastNonConfigurationInstances;
//窗口需要使用WindowManager
mWindow.setWindowManager(null, mToken, mComponent.flattenToString(),
(info.flags&ActivityInfo.FLAG_HARDWARE_ACCELERATED)!=0);
if(mParent!=null){
mWindow.setContainer(mParent.getWindow());
}
mWindowManager=mWindow.getWindowManager();
mCurrentConfig=config;
}
可见,Activity通过attach方法将大量信息附加到自身,这些信息包括Context、Fragmen tManager、UI线程和主线程、PhoneWindow等,这样便构建了完整的Activity运行框架。
以上处理过程的主要流程如图11-5所示。
图 11-5 performLaunchActivity方法执行流程
performLaunchActivity方法执行完毕后,进入显示Activity的第五个主要步骤。
5.ActivityThread.handleResumeActivity
显示Activity的第五步由ActivityThread.handleResumeActivity方法完成,代码如下:
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward){
unscheduleGcIdler();
//回调onResume方法
ActivityClientRecord r=performResumeActivity(token, clearHide);
if(r!=null){
final Activity a=r.activity;
……
/*此时mStartedActivity为false。如果该值为true,说明
上一个Activity还在执行onResume方法/
boolean willBeVisible=!a.mStartedActivity;
if(!willBeVisible){//本例为true,表示该Activity是否可见
try{
willBeVisible=ActivityManagerNative.getDefault()
.willActivityBeVisible(a.getActivityToken());
}catch(RemoteException e){
}
}
if(r.window==null&&!a.mFinished&&willBeVisible){
r.window=r.activity.getWindow();
View decor=r.window.getDecorView();//设置根View
decor.setVisibility(View.INVISIBLE);
ViewManager wm=a.getWindowManager();
WindowManager.LayoutParams l=r.window.getAttributes();
a.mDecor=decor;
l.type=WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode|=forwardBit;
if(a.mVisibleFromClient){
a.mWindowAdded=true;
wm.addView(decor, l);
}
}else if(!willBeVisible){
//如果Activity在onResume时,启动了另一个Activity,此时窗口不可见
r.hideForNow=true;
}
if(!r.activity.mFinished&&willBeVisible
&&r.activity.mDecor!=null&&!r.hideForNow){
……
r.activity.mVisibleFromServer=true;
mNumVisibleActivities++;//当前屏幕可见Activity数,此时为1
if(r.activity.mVisibleFromClient){
r.activity.makeVisible();
}
}
if(!r.onlyLocalRequest){//满足该分支的条件
r.nextIdle=mNewActivities;
mNewActivities=r;
//onResume后进入Idle状态,此时将向主线程的消息队列注册IdleHandler
Looper.myQueue().addIdleHandler(new Idler());
}
r.onlyLocalRequest=false;
}else{
……//onResume时出现异常,直接destroy该Activity
ActivityThread. handleResumeActivity方法首先会回调Activity的onResume方法,然后设置Activity对应的View可见,最后向应用程序主线程的消息循环中添加一个Idle状态的处理器:Idler对象。
可见,当Activity执行完onResume方法后,会进入Idle状态。当应用程序主线程的消息队列中没有其他要处理的消息时,将处理Idle消息,进而调用Idler对象的queueIdle方法。相关内容请参考第7章。
6.ActivityThread.performResumeActivity
显示Activity的第六步是回调Activity的onResume方法,由ActivityThread.performResume Activity完成,代码如下:
public final ActivityClientRecord performResumeActivity(IBinder token,
boolean clearHide){
ActivityClientRecord r=mActivities.get(token);
if(r!=null&&!r.activity.mFinished){//本例为true
if(clearHide){//false
r.hideForNow=false;
r.activity.mStartedActivity=false;
}
try{
if(r.pendingIntents!=null){
//调用Activity生命周期的onNewIntent方法
deliverNewIntents(r, r.pendingIntents);
r.pendingIntents=null;
}
if(r.pendingResults!=null){
//调用Activity生命周期的onActivityResult方法
deliverResults(r, r.pendingResults);
r.pendingResults=null;
}
//调用Activity生命周期的onResume方法
r.activity.performResume();
r.paused=false;//此时真正进入非暂停状态
r.stopped=false;//此时真正进入非停止状态
r.state=null;
}
……
return r;
}
可见ActivityThread.performResumeActivity在回调Activity生命周期的onResume方法之前,还可能回调onNewIntent和onActivityResult方法。这里只分析如何回调onResume方法。
7.performResume
显示Activity的第七步是ActivityThread.performResumeActivity调用Activity的performResume方法,回调其生命周期的onResume方法,代码如下:
final void performResume(){
//如果当前Activity处于stop状态,依次调用Activity生命周期的onRestart和onStart方法
performRestart();
//执行Activity的Fragment的事务
mFragments.execPendingActions();
mLastNonConfigurationInstances=null;
mCalled=false;
//调用Activity生命周期的onResume方法
mInstrumentation.callActivityOnResume(this);
……
mFragments.dispatchResume();//Fragment切换到Resume状态
mFragments.execPendingActions();
//执行Activity生命周期的onPostResume方法
onPostResume();
……
}
可见onResume方法并非孤立执行的,如果当前Activity处于stop状态,需要首先回调其onRestart和onStart方法,然后再执行onResume方法,最后还需要执行onPostResume方法[1]。
以上处理过程的主要流程如图11-6所示。
图 11-6 Activity的performResume方法执行流程
以上步骤执行完毕后返回ActivityStack.realStartActivityLocked方法,继续执行ActivityStack.completeResumeLocked方法。
8.ActivityStack.completeResumeLocked
显示Activity的第八步,当Activity执行完onResume方法返回ActivityManagerService进程后,需要调用ActivityStack.completeResumeLocked方法执行Activity.onResume的后续处理。代码如下:
private final void completeResumeLocked(ActivityRecord next){
next.idle=false;
next.results=null;
next.newIntents=null;
//Activity.onResume后会向应用程序主线程中添加Idle状态处理器
//ActivityManagerService通过IDLE_TIMEOUT_MSG消息监控其处理情况
Message msg=mHandler.obtainMessage(IDLE_TIMEOUT_MSG);
msg.obj=next;
mHandler.sendMessageDelayed(msg, IDLE_TIMEOUT);
if(mMainStack){
mService.reportResumedActivityLocked(next);
}
next.clearThumbnail();
if(mMainStack){
mService.setFocusedActivityLocked(next);//设置当前获取焦点的Activity
}
next.resumeKeyDispatchingLocked();
ensureActivitiesVisibleLocked(null,0);
mService.mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
……
}
当Activity执行其onResume方法,并向应用程序主线程中加入Idle消息处理器后,ActivityStack向自身消息循环中发送IDLE_TIMEOUT_MSG消息,并指定该消息在10s后处理。接下来分析Activity Idle状态的处理过程。
[1]这里涉及Fragment运行,不在本书中讲解,读者可以参考Android官方开发者网站http://developer.android.com/reference/android/app/Fragment/html。