Android 70 ActivityManagerService4 启动Activity的过程三.docx
- 文档编号:17260071
- 上传时间:2023-07-23
- 格式:DOCX
- 页数:18
- 大小:104.18KB
Android 70 ActivityManagerService4 启动Activity的过程三.docx
《Android 70 ActivityManagerService4 启动Activity的过程三.docx》由会员分享,可在线阅读,更多相关《Android 70 ActivityManagerService4 启动Activity的过程三.docx(18页珍藏版)》请在冰点文库上搜索。
Android70ActivityManagerService4启动Activity的过程三
Android7.0ActivityManagerService(4)启动Activity的过程:
三
一、startPausingLocked函数
根据启动Activity的过程:
一,我们知道在启动Activity的过程中,当已经将Activity对应的Task移动到前台,同时将待启动的Activity放置到栈顶后,将会调用ActivityStack中的resumeTopActivityInnerLocked函数,在该函数中:
privatebooleanresumeTopActivityInnerLocked(......){
...........
//mResumedActivity保存者当前在前台显示的Activity
if(mResumedActivity!
=null){
.............
//调用startPausingLocked函数,中断正在显示的Activity
pausing|=startPausingLocked(userLeaving,false,true,dontWaitForPause);
}
if(pausing){
..........
returntrue;
}..........
............
}
此处,跟进一下startPausingLocked函数:
//Startpausingthecurrentlyresumedactivity.
finalbooleanstartPausingLocked(booleanuserLeaving,booleanuiSleeping,booleanresuming,
booleandontWait){
.................
//mResumedActivity保存着当前正在显示的Activity
ActivityRecordprev=mResumedActivity;
.................
mResumedActivity=null;
//mPausingActivity保存准备中断的Activity
mPausingActivity=prev;
................
//更新状态
prev.state=ActivityState.PAUSING;
................
if(prev.app!
=null&&prev.app.thread!
=null){
................
try{
............
//通知该Activity所在的进程,调用schedulePauseActivity函数
prev.app.thread.schedulePauseActivity(prev.appToken,prev.finishing,
userLeaving,prev.configChangeFlags,dontWait);
}catch(Exceptione){
...............
}
}else{
..............
}
//Ifwearenotgoingtosleep,wewanttoensurethedeviceis
//awakeuntilthenextactivityisstarted.
if(!
uiSleeping&&!
mService.isSleepingOrShuttingDownLocked()){
//在启动Activity的第二部分中提过
//该WakeLock防止在Activity切换过程中,系统发生休眠
//当Activity切换成功后,将会释放该WakeLock
mStackSupervisor.acquireLaunchWakelock();
}
if(mPausingActivity!
=null){
//Havethewindowmanagerpauseitskeydispatchinguntilthenew
//activityhasstarted.Ifwe'repausingtheactivityjustbecause
//thescreenisbeingturnedoffandtheUIissleeping,don'tinterrupt
//keydispatch;thesameactivitywillpickitupagainonwakeup.
if(!
uiSleeping){
//暂停输入事件的派发
prev.pauseKeyDispatchingLocked();
}........
.........
if(dontWait){
//Ifthecallersaidtheydon'twanttowaitforthepause,thencomplete
//thepausenow.
completePauseLocked(false);
returnfalse;
}else{
//Scheduleapausetimeoutincasetheappdoesn'trespond.
//Wedon'tgiveitmuchtimebecausethisdirectlyimpactsthe
//responsivenessseenbytheuser.
Messagemsg=mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
msg.obj=prev;
prev.pauseTime=SystemClock.uptimeMillis();
//延迟时间500ms,当这个消息被处理时,也会调用completePauseLocked函数
mHandler.sendMessageDelayed(msg,PAUSE_TIMEOUT);
}
}else{
.............
}
}
容易看出,这段代码最主要的操作是与应用进程的ApplicationThread进行Binder通信,调用其schedulePauseActivity函数。
与之前的流程一样,ApplicationThread仅作为通信接口,它将发送消息触发进程的ActivityThread调用handlePauseActivity进行实际的操作。
二、handlePauseActivity函数
privatevoidhandlePauseActivity(IBindertoken,booleanfinished,
booleanuserLeaving,intconfigChanges,booleandontReport,intseq){
ActivityClientRecordr=mActivities.get(token);
..............
if(r!
=null){
..............
r.activity.mConfigChangeFlags|=configChanges;
//执行pause的实际操作
performPauseActivity(token,finished,r.isPreHoneycomb(),"handlePauseActivity");
..............
//Telltheactivitymanagerwehavepaused.
if(!
dontReport){
try{
//通知AMS
ActivityManagerNative.getDefault().activityPaused(token);
}catch(RemoteExceptionex){
throwex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged=true;
}
}
这段代码比较简单,就是调用performPauseActivity完成中断Activity的实际工作,然后再通过Binder通信通知AMS中断完成。
我们稍微看一下performPauseActivity函数:
finalBundleperformPauseActivity(IBindertoken,booleanfinished,
booleansaveState,Stringreason){
ActivityClientRecordr=mActivities.get(token);
returnr!
=null?
performPauseActivity(r,finished,saveState,reason):
null;
}
finalBundleperformPauseActivity(ActivityClientRecordr,booleanfinished,
booleansaveState,Stringreason){
................
//Nexthavetheactivitysaveitscurrentstateandmanageddialogs...
if(!
r.activity.mFinished&&saveState){
//完成调用Activity的onSaveInstanceState接口等操作
callCallActivityOnSaveInstanceState(r);
}
//调用Activity的onPause接口
performPauseActivityIfNeeded(r,reason);
//Notifyanyoutstandingonpausedlisteners
ArrayList
synchronized(mOnPauseListeners){
//ActivityThread提供了对外接口registerOnActivityPausedListener
//可以注册观察者监听某个Activity进入paused状态
listeners=mOnPauseListeners.remove(r.activity);
}
intsize=(listeners!
=null?
listeners.size():
0);
for(inti=0;i //回调 listeners.get(i).onPaused(r.activity); } return! r.activity.mFinished&&saveState? r.state: null; } performPauseActivity整体的逻辑很清晰,就是调用Activity生命周期中对应的接口,同时通知观察者Activitypaused。 现在我们将视线移回到AMS,看看定义于其中的activityPaused函数。 publicfinalvoidactivityPaused(IBindertoken){ finallongorigId=Binder.clearCallingIdentity(); synchronized(this){ ActivityStackstack=ActivityRecord.getStackLocked(token); if(stack! =null){ stack.activityPausedLocked(token,false); } } Binder.restoreCallingIdentity(origId); } 从上面的代码可以看出,activityPaused的主要工作将交给ActivityStack的activityPausedLocked函数: finalvoidactivityPausedLocked(IBindertoken,booleantimeout){ ............... finalActivityRecordr=isInStackLocked(token); if(r! =null){ //从消息队列中移除该事件 mHandler.removeMessages(PAUSE_TIMEOUT_MSG,r); if(mPausingActivity==r){ .............. completePauseLocked(true); return; }else{ ................ } } ............... } 上述代码中的completePauseLocked函数,将负责完成本次中断Activity的剩余的工作,同时重新进入启动Activity的流程。 //此处resumeNext的值为true privatevoidcompletePauseLocked(booleanresumeNext){ ActivityRecordprev=mPausingActivity; .................. if(prev! =null){ finalbooleanwasStopping=prev.state==ActivityState.STOPPING; prev.state=ActivityState.PAUSED; if(prev.finishing){ ................ //如果已经进入finishing状态,调用finishCurrentActivityLocked(本流程中,Activity还没有finishing) //此处参数为FINISH_AFTER_VISIBLE,仅将Activity加入到mStoppingActivities中 prev=finishCurrentActivityLocked(prev,FINISH_AFTER_VISIBLE,false); }elseif(prev.app! =null){ ................. //将Activity从等待可见的Activity中移除 if(mStackSupervisor.mWaitingVisibleActivities.remove(prev)){ ................... } if(prev.deferRelaunchUntilPaused){ ............. }elseif(wasStopping){ ............. }elseif((! prev.visible&&! hasVisibleBehindActivity()) ||mService.isSleepingOrShuttingDownLocked()){ //IfwewerevisiblethenresumeTopActivitieswillreleaseresourcesbefore //stopping. //如果Activity变为不可见时,才会进入此分支,本流程实际上不会直接进入该分支 //但当Activity真的不见了,ActivityStack将调用makeInvisible,重新对中断Activity调用addToStopping函数 //将暂停的Activity保存mStoppingActivities中 addToStopping(prev,true/*immediate*/); } }else{ .................. } .......... //将mPausingActivity置为null mPausingActivity=null; } if(resumeNext){ finalActivityStacktopStack=mStackSupervisor.getFocusedStack(); if(! mService.isSleepingOrShuttingDownLocked()){ //将重新开始启动前台栈顶的Activity,由于此时mResumedActivity为null,于是进入到启动目标Activity的流程 mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack,prev,null); }else{ .............. } } if(prev! =null){ //将启动新的Activity,可以恢复事件分发 prev.resumeKeyDispatchingLocked(); .................. } ................ } 这部分代码的主要工作是: 1、若中断的Activity变为不可见时,调用addToStopping函数,将中断的Activity加入到mStoppingActivities; 2、将mPausingActivity置为null后,重新进入启动目标Activity的流程。 虽然本流程不会直接调用addToStopping函数,但我们还是进一步看看,中断之后的Activity变为不可见后将如何被AMS处理。 三、addToStopping函数 //此流程中immediate的值为true privatevoidaddToStopping(ActivityRecordr,booleanimmediate){ if(! mStackSupervisor.mStoppingActivities.contains(r)){ mStackSupervisor.mStoppingActivities.add(r); } //Ifwealreadyhaveafewactivitieswaitingtostop,thengiveup //onthingsgoingidleandstartclearingthemout.Orifristhe //lastofactivityofthelasttaskthestackwillbeemptyandmust //beclearedimmediately. //原生中MAX_STOPPING_TO_FORCE的值为3 booleanforceIdle=mStackSupervisor.mStoppingActivities.size()>MAX_STOPPING_TO_FORCE ||(r.frontOfTask&&mTaskHistory.size()<=1); if(immediate||forceIdle){ ............ //ActivityStackSupervisor发送消息IDLE_NOW_MSG,最终由activityIdleInternalLocked函数处理 mStackSupervisor.scheduleIdleLocked(); }else{ ................ } } 从上面的代码,可以看出启动Activity和中断Activity的最后一部均是调用activityIdleInternalLocked函数, 我们看看该函数中处理中断的Activity相关的流程: //中断Activity时,fromTimeout的值为true finalActivityRecordactivityIdleInternalLocked(finalIBindertoken,booleanfromTimeout, Configurationconfig){ ............... ActivityRecordr=ActivityRecord.forTokenLocked(token); if(r! =null){ ......... if(fromTimeout){ //该函数中也会调用mService.notifyAll(),因此会唤醒等待Activity启动的ActivityStarter //但ActivityStarter会检测到目标Activity还未可见,因此会重新进入等待状态 reportActivityLaunchedLocked(fromTimeout,r,-1,-1); } ......... } ......... //Atomicallyretrievealloftheotherthingstodo. finalArrayList NS=stops! =null? stops.size(): 0; .......... //Stopanyactivitiesthatarescheduledtodosobuthavebeen //waitingforthenextonetostart. for(inti=0;i r=stops.get(i); finalActivityStackstack=r.task.stack; if(stack! =null){ if(r.finishing){ stack.finishCurrentActivityLocked(r,ActivityStack.FINISH_IMMEDIATELY,false); }else{ //调用ActivityStack的stopActivityLocked函数 stack.stopActivityLocked(r); } } } //AMS处理无用的进程等 ............... } 跟进一下ActivityStack的stopActivityLocked函数:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 70 ActivityManagerService4 启动Activity的过程三 启动 Activity 过程
链接地址:https://www.bingdoc.com/p-17260071.html