11.2.7 停止源Activity

当目标Activity的onCreate、onStart、onResume等方法执行完毕,且activityIdleInternal方法执行后,进入启动应用程序Activity的第七阶段:停止源Activity。处理的主要流程如图11-7所示。

11.2.7 停止源Activity - 图1

图 11-7 停止源Activity流程

1.ActivityStack.stopActivityLocked

这里从ActivityStack.stopActivityLocked方法开始分析,代码如下:


private final void stopActivityLocked(ActivityRecord r){

//处理FLAG_ACTIVITY_NO_HISTORY启动标记,本例不满足该分支条件

if((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY)!=0

||(r.info.flags&ActivityInfo.FLAG_NO_HISTORY)!=0){

if(!r.finishing){

if(!mService.mSleeping){

requestFinishActivityLocked(r.appToken,

Activity.RESULT_CANCELED, null,"no-history");

}else{

}

}

}

if(r.app!=null&&r.app.thread!=null){

if(mMainStack){

//如果当前要停止的Activity占有焦点,则需要将焦点切换给栈顶Activity

if(mService.mFocusedActivity==r){

mService.setFocusedActivityLocked(

topRunningActivityLocked(null));

}

}

r.resumeKeyDispatchingLocked();

try{

r.stopped=false;

r.state=ActivityState.STOPPING;//切换状态为stopping

……

//调用ApplicationThreadProxy的scheduleStopActivity方法

r.app.thread.scheduleStopActivity(r.appToken,

r.visible, r.configChangeFlags);

if(mService.isSleeping()){

//如果ActivityManagerService休眠,则当前停止的Activity也休眠

r.setSleeping(true);

}

//stop操作不能超过指定时间,通过STOP_TIMEOUT_MSG消息处理stop超时

Message msg=mHandler.obtainMessage(STOP_TIMEOUT_MSG);

msg.obj=r;

mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);

}catch(Exception e){

r.stopped=true;

r.state=ActivityState.STOPPED;

if(r.configDestroy){

destroyActivityLocked(r, true, false,"stop-except");

}

}

}


stopActivityLocked的主要工作由以下3部分组成:

处理FLAG_ACTIVITY_NO_HISTORY启动标记。设置了FLAG_ACTIVITY_NO_HISTORY启动标记的Activity,将不会放入栈中,此时需要销毁该Activity。

调用ApplicationThreadProxy的scheduleStopActivity方法调度Activity。这里主要调用Activity生命周期的onStop方法。

向ActivityStack的消息队列中发送STOP_TIMEOUT_MSG消息,并指定该消息在STOP_TIMEOUT(10s)后处理。

2.scheduleStopActivity

scheduleStopActivity方法在应用程序进程中执行,ActivityManagerService需要跟踪该方法的执行结果,因此向ActivityStack的消息队列中发送STOP_TIMEOUT_MSG消息。如果该消息不能在STOP_TIMEOUT指定的时间(10s)内被移除,则说明scheduleStopActivity方法执行超时。

ApplicationThreadProxy. scheduleStopActivity方法通过Binder通信,进而调用ApplicationThread的同名方法完成操作,代码如下:


public final class ActivityThread{

……

final H mH=new H();

……

private class ApplicationThread extends ApplicationThreadNative{

public final void scheduleStopActivity(IBinder token,

boolean showWindow, int configChanges){

queueOrSendMessage(

showWindow?H.STOP_ACTIVITY_SHOW:H.STOP_ACTIVITY_HIDE,

token,0,configChanges);

}

……


scheduleStopActivity方法根据当前要停止的Activity是否可见(参数showWindow)分别向应用程序主线程中发送STOP_ACTIVITY_SHOW和STOP_ACTIVITY_HIDE消息,这两个消息将在ActivityThread.mH的handleMessage方法中处理,代码如下:


public final class ActivityThread{

……

final H mH=new H();

……

private class H extends Handler{

public void handleMessage(Message msg){

case STOP_ACTIVITY_SHOW:

handleStopActivity((IBinder)msg.obj, true, msg.arg2);

break;

case STOP_ACTIVITY_HIDE:

handleStopActivity((IBinder)msg.obj, false, msg.arg2);

break;

……


3.handleStopActivity

可见,不管当前要停止的Activity是否可见,都需要调用handleStopActivity方法。该方法定义于ActivityThread中,代码如下:


private void handleStopActivity(IBinder token, boolean show, int configChanges){

//从ActivityThread取出该Activity的信息

ActivityClientRecord r=mActivities.get(token);

r.activity.mConfigChangeFlags|=configChanges;

StopInfo info=new StopInfo();

//将请求转发给performStopActivityInner方法

performStopActivityInner(r, info, show, true);

updateVisibility(r, show);

//Honey comb之前版本需要保证异步操作完成

if(!r.isPreHoneycomb()){

QueuedWork.waitToFinish();

}

info.activity=r;

info.state=r.state;

//stop操作完成,通知ActivityManagerService

mH.post(info);

}


handleStopActivity的主要工作由performStopActivityInner方法和mH.post方法完成,前者用于回调Activity生命周期的onSaveInstanceState方法和onStop方法,后者用于通知ActivityManagerService, stop操作完成。

4.performStopActivityInner

首先分析performStopActivityInner方法,该方法定义于ActivityThread中,代码如下:


private void performStopActivityInner(ActivityClientRecord r,

StopInfo info, boolean keepShown, boolean saveState){

Bundle state=null;

if(r!=null){

……

//如果Activity需要保存当前状态,回调其onSaveInstanceState方法

if(!r.activity.mFinished&&saveState){//本例满足该条件

if(r.state==null){

state=new Bundle();

state.setAllowFds(false);

mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);

r.state=state;

}else{

state=r.state;

}

}

if(!keepShown){

try{

r.activity.performStop();//回调Activity的onStop方法

}catch(Exception e){

……

}

r.stopped=true;//更新状态为stop

}

r.paused=true;

}

}


performStopActivityInner方法的主要工作是,通过Instrumentation调用Activity生命周期的onSaveInstanceState和onStop方法。

performStopActivityInner方法执行完毕后,返回handleStopActivity方法,继续执行mH.post方法,该方法的参数是StopInfo,该参数实现了Runnable。已知mH是Handler类型的对象,因此其post方法将接收到的StopInfo参数封装成消息发送到ActivityThread的消息循环中。ActivityThread停止Activity后,应该通知ActivityManagerService操作完毕,为什么要向自身的消息循环中发送消息呢?

5.StopInfo

接下来分析StopInfo,代码如下:


private static class StopInfo implements Runnable{

ActivityClientRecord activity;

Bundle state;

Bitmap thumbnail;

CharSequence description;

@Override public void run(){

try{

//调用ActivityManagerProxy的activityStopped方法

ActivityManagerNative.getDefault().activityStopped(

activity.token, state, thumbnail, description);

}catch(RemoteException ex){

}

}

}


当ActivityThread的消息处理器处理StopInfo所在的消息时,会通过ActivityManagerProxy的activityStopped方法通知ActivityManagerService停止Activity的操作完成。

至此应用程序Activity的启动过程就分析完了。