finishCurrentActivityLocked(r, FINISH_IMMEDIATELY); } else {
stopActivityLocked(r); } } }
for (i=0; i
HistoryRecord r = (HistoryRecord)finishes.get(i); synchronized (this) {
destroyActivityLocked(r, true); } }
这个NS的值是通过 stops = processStoppingActivitiesLocked(true); NS = stops != null ? stops.size() : 0;
的方式取得的,processStoppingActivitiesLocked逻辑如下:
processStoppingActivitiesLocked( boolean remove)N = mStoppingActivities.sizenowVisible = mResumedActivity != null && mResumedActivity.nowVisible && !mResumedActivity.waitingVisiblefor (int i=0; i
面加入的;
mResumedActivity这时候为null(在startPausingLocked里面已经被设了); nowVisible表示当前是否是可见;
waitingVisble,表示正在等待某个activity变成visible;
对于我们讨论的情景,除了waitingVisbile为true的activity都会被加入到stops里面,最后返回的
就是stops;
同理,NF的值为NF=mFinishingActivities.size()也就是正在finishing的activity的列表;
?Tech, 2010-2-5
Page 29 of 38
后面就开始处理这两个数组;
activityIdleInternal(IBinder token, boolean fromTimeout,Configuration config)for (i=0; i
如果此记录正在结束,那么就调用finishCurrentActivityLocked来完成,它或者导致把这个activity
加入到finisheds里面,或者就直接被destory;
否则就调用stopActivityLocked来停止; 右边一路是处理需要结束的activity; 先从finishes里面取出记录;
然后调用destoryActivityLocked来结束,这里会导致onDestory的调用,这条路径我们就不分析了,
因为一般的应用很少会重载这个函数;
现在重点看看stopActivityLocked函数;
?Tech, 2010-2-5 Page 30 of 38
stopActivityLocked(HistoryRecord r)if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0 || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0)if (mFocusedActivity == r)r.resumeKeyDispatchingLockedelse if (r.app != null && r.app.thread != null)r.stopped = false这个值要到activityStopped里面才会被设置成true;r.state = ActivityState.STOPPINGif (!r.visible)r.app.thread.scheduleStopActivity(r, r.visible, r.configChangeFlags)if (!r.finishing) setFocusedActivityLocked(topRunningActivityLocked(null))mWindowManager.setAppVisibility(r, false);requestFinishActivityLocked(r, Activity.RESULT_CANCELED, null, \这里应该是结束Activity,也就是destory掉
最左边的路径是destory此activity;
然后考虑此activity是否是focus activity,如果是,那么需要切换焦点;
开启键盘事件分发,在startPausingLocked函数里面会有下面的调用,这里uiSleeping为false; if (!uiSleeping) {
prev.pauseKeyDispatchingLocked(); }
目的就是暂停正在被pause的窗口的键盘事件分发;
设置标志位stopped,这个标志位会在真正stop后设置为true;
如果这个记录不可见了,那么就告诉windowManager,需要隐藏它了; 然后通过r.app.thread.scheduleStopActivity开启停止流程了;
scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) queueOrSendMessage( showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE, token, 0, configChanges)
都是很类似的逻辑,就是放一个消息到队列里面;
?Tech, 2010-2-5 Page 31 of 38
handleMessage(Message msg)case STOP_ACTIVITY_SHOWcase STOP_ACTIVITY_HIDEhandleStopActivity((IBinder)msg.obj, true, msg.arg2)handleStopActivity(IBinder token, boolean show, int configChanges) ActivityThread.javahandleStopActivity((IBinder)msg.obj, false, msg.arg2)ActivityRecord r = mActivities.get(token)performStopActivityInner(r, info, show)updateVisibility(r, show)ActivityManagerNative.getDefault().activityStopped( r.token, info.thumbnail, info.description)BinderactivityStopped(IBinder token, Bitmap thumbnail,CharSequence description)ActivityManagerService.java这里有可能触发onDestory的执行如果configDestroy为真
这个消息很有意思,分为STOP_ACTIVITY_SHOW,以及STOP_ACTIVITY_HIDE,最后都是调用
handleStopActivity来处理,只是中间的这个参数不一样;差别在于,为true的时候,即使停止了,也会在屏幕上看到直到被新的activity给覆盖,为false将会被隐藏掉; 函数handleStopActivity的逻辑也不复杂, 首先取得这个ActivityRecord,然后开始走向Stop流程; 接着更新这个activity的显示情况,该show就show,该hide就hide; 最后通过ActivityStopped通知ActivityManagerService activity已经停止了,这里如果configDestory配置为true,将会导致activity的destory; 好现在继续看看这个stop的流程,也就是函数performStopActivityInner;
?Tech, 2010-2-5 Page 32 of 38