Android Activity原理分析 联系客服

发布时间 : 星期五 文章Android Activity原理分析更新完毕开始阅读de01183543323968011c92f9

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