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