Step 8. ActivityStack.startActivityLocked 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
        
  1. public classActivityStack{
  2. ......
  3. final intstartActivityLocked(IApplicationThreadcaller,
  4. Intentintent,StringresolvedType,
  5. Uri[]grantedUriPermissions,
  6. intgrantedMode,ActivityInfoaInfo,IBinderresultTo,
  7. StringresultWho, intrequestCode,
  8. intcallingPid, intcallingUid, booleanonlyIfNeeded,
  9. booleancomponentSpecified){
  10. interr=START_SUCCESS;
  11. ProcessRecordcallerApp= null;
  12. if(caller!= null){
  13. callerApp=mService.getRecordForAppLocked(caller);
  14. if(callerApp!= null){
  15. callingPid=callerApp.pid;
  16. callingUid=callerApp.info.uid;
  17. } else{
  18. ......
  19. }
  20. }
  21. ......
  22. ActivityRecordsourceRecord= null;
  23. ActivityRecordresultRecord= null;
  24. if(resultTo!= null){
  25. intindex=indexOfTokenLocked(resultTo);
  26. ......
  27. if(index>= 0){
  28. sourceRecord=(ActivityRecord)mHistory.get(index);
  29. if(requestCode>= 0&&!sourceRecord.finishing){
  30. ......
  31. }
  32. }
  33. }
  34. intlaunchFlags=intent.getFlags();
  35. if((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT)!= 0
  36. &&sourceRecord!= null){
  37. ......
  38. }
  39. if(err==START_SUCCESS&&intent.getComponent()== null){
  40. ......
  41. }
  42. if(err==START_SUCCESS&&aInfo== null){
  43. ......
  44. }
  45. if(err!=START_SUCCESS){
  46. ......
  47. }
  48. ......
  49. ActivityRecordr= newActivityRecord(mService, this,callerApp,callingUid,
  50. intent,resolvedType,aInfo,mService.mConfiguration,
  51. resultRecord,resultWho,requestCode,componentSpecified);
  52. ......
  53. returnstartActivityUncheckedLocked(r,sourceRecord,
  54. grantedUriPermissions,grantedMode,onlyIfNeeded, true);
  55. }
  56. ......
  57. }
从传进来的参数caller得到调用者的进程信息,并保存在callerApp变量中,这里就是Launcher应用程序的进程信息了。 前面说过,参数resultTo是Launcher这个Activity里面的一个Binder对象,通过它可以获得Launcher这个Activity的相关信息,保存在sourceRecord变量中。
再接下来,创建即将要启动的Activity的相关信息,并保存在r变量中:
            
  1. ActivityRecordr= newActivityRecord(mService, this,callerApp,callingUid,
  2. intent,resolvedType,aInfo,mService.mConfiguration,
  3. resultRecord,resultWho,requestCode,componentSpecified);
接着调用startActivityUncheckedLocked函数进行下一步操作。 Step 9. ActivityStack.startActivityUncheckedLocked 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
        
  1. public classActivityStack{
  2. ......
  3. final intstartActivityUncheckedLocked(ActivityRecordr,
  4. ActivityRecordsourceRecord,Uri[]grantedUriPermissions,
  5. intgrantedMode, booleanonlyIfNeeded, booleandoResume){
  6. finalIntentintent=r.intent;
  7. final intcallingUid=r.launchedFromUid;
  8. intlaunchFlags=intent.getFlags();
  9. //We'llinvokeonUserLeavingbeforeonPauseonlyifthelaunching
  10. //activitydidnotexplicitlystatethatthisisanautomatedlaunch.
  11. mUserLeaving=(launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION)== 0;
  12. ......
  13. ActivityRecordnotTop=(launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
  14. != 0?r: null;
  15. //IftheonlyIfNeededflagisset,thenwecandothisiftheactivity
  16. //beinglaunchedisthesameastheonemakingthecall...or,as
  17. //aspecialcase,ifwedonotknowthecallerthenwecountthe
  18. //currenttopactivityasthecaller.
  19. if(onlyIfNeeded){
  20. ......
  21. }
  22. if(sourceRecord== null){
  23. ......
  24. } else if(sourceRecord.launchMode==ActivityInfo.LAUNCH_SINGLE_INSTANCE){
  25. ......
  26. } else if(r.launchMode==ActivityInfo.LAUNCH_SINGLE_INSTANCE
  27. ||r.launchMode==ActivityInfo.LAUNCH_SINGLE_TASK){
  28. ......
  29. }
  30. if(r.resultTo!= null&&(launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK)!= 0){
  31. ......
  32. }
  33. booleanaddingToTask= false;
  34. if(((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK)!= 0&&
  35. (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK)== 0)
  36. ||r.launchMode==ActivityInfo.LAUNCH_SINGLE_TASK
  37. ||r.launchMode==ActivityInfo.LAUNCH_SINGLE_INSTANCE){
  38. //Ifbringtofrontisrequested,andnoresultisrequested,and
  39. //wecanfindataskthatwasstartedwiththissame
  40. //component,theninsteadoflaunchingbringthatonetothefront.
  41. if(r.resultTo== null){
  42. //Seeifthereisatasktobringtothefront.Ifthisis
  43. //aSINGLE_INSTANCEactivity,therecanbeoneandonlyone
  44. //instanceofitinthehistory,anditisalwaysinitsown
  45. //uniquetask,sowedoaspecialsearch.
  46. ActivityRecordtaskTop=r.launchMode!=ActivityInfo.LAUNCH_SINGLE_INSTANCE
  47. ?findTaskLocked(intent,r.info)
  48. :findActivityLocked(intent,r.info);
  49. if(taskTop!= null){
  50. ......
  51. }
  52. }
  53. }
  54. ......
  55. if(r.packageName!= null){
  56. //Iftheactivitybeinglaunchedisthesameastheonecurrently
  57. //atthetop,thenweneedtocheckifitshouldonlybelaunched
  58. //once.
  59. ActivityRecordtop=topRunningNonDelayedActivityLocked(notTop);
  60. if(top!= null&&r.resultTo== null){
  61. if(top.realActivity.equals(r.realActivity)){
  62. ......
  63. }
  64. }
  65. } else{
  66. ......
  67. }
  68. booleannewTask= false;
  69. //Shouldthisbeconsideredanewtask?
  70. if(r.resultTo== null&&!addingToTask
  71. &&(launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK)!= 0){
  72. //todo:shoulddobettermanagementofintegers.
  73. mService.mCurTask++;
  74. if(mService.mCurTask<= 0){
  75. mService.mCurTask= 1;
  76. }
  77. r.task= newTaskRecord(mService.mCurTask,r.info,intent,
  78. (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH)!= 0);
  79. ......
  80. newTask= true;
  81. if(mMainStack){
  82. mService.addRecentTaskLocked(r.task);
  83. }
  84. } else if(sourceRecord!= null){
  85. ......
  86. } else{
  87. ......
  88. }
  89. ......
  90. startActivityLocked(r,newTask,doResume);
  91. returnSTART_SUCCESS;
  92. }
  93. ......
  94. }
函数首先获得intent的标志值,保存在launchFlags变量中。 这个intent的标志值的位Intent.FLAG_ACTIVITY_NO_USER_ACTION没有置位,因此 ,成员变量mUserLeaving的值为true。 这个intent的标志值的位Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP也没有置位,因此,变量notTop的值为null。 由于在这个例子的AndroidManifest.xml文件中,MainActivity没有配置launchMode属值,因此,这里的r.launchMode为默认值0,表示以标准(Standard,或者称为ActivityInfo.LAUNCH_MULTIPLE)的方式来启动这个Activity。Activity的启动方式有四种,其余三种分别是ActivityInfo.LAUNCH_SINGLE_INSTANCE、ActivityInfo.LAUNCH_SINGLE_TASK和ActivityInfo.LAUNCH_SINGLE_TOP,具体可以参考官方网站 http://developer.android.com/reference/android/content/pm/ActivityInfo.html。 传进来的参数r.resultTo为null,表示Launcher不需要等这个即将要启动的MainActivity的执行结果。 由于这个intent的标志值的位Intent.FLAG_ACTIVITY_NEW_TASK被置位,而且Intent.FLAG_ACTIVITY_MULTIPLE_TASK没有置位,因此,下面的if语句会被执行:
        
  1. if(((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK)!= 0&&
  2. (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK)== 0)
  3. ||r.launchMode==ActivityInfo.LAUNCH_SINGLE_TASK
  4. ||r.launchMode==ActivityInfo.LAUNCH_SINGLE_INSTANCE){
  5. //Ifbringtofrontisrequested,andnoresultisrequested,and
  6. //wecanfindataskthatwasstartedwiththissame
  7. //component,theninsteadoflaunchingbringthatonetothefront.
  8. if(r.resultTo== null){
  9. //Seeifthereisatasktobringtothefront.Ifthisis
  10. //aSINGLE_INSTANCEactivity,therecanbeoneandonlyone
  11. //instanceofitinthehistory,anditisalwaysinitsown
  12. //uniquetask,sowedoaspecialsearch.
  13. ActivityRecordtaskTop=r.launchMode!=ActivityInfo.LAUNCH_SINGLE_INSTANCE
  14. ?findTaskLocked(intent,r.info)
  15. :findActivityLocked(intent,r.info);
  16. if(taskTop!= null){
  17. ......
  18. }
  19. }
  20. }
这段代码的逻辑是查看一下,当前有没有Task可以用来执行这个Activity。由于r.launchMode的值不为ActivityInfo.LAUNCH_SINGLE_INSTANCE,因此,它通过findTaskLocked函数来查找存不存这样的Task,这里返回的结果是null,即taskTop为null,因此,需要创建一个新的Task来启动这个Activity。 接着往下看:
        
  1. if(r.packageName!= null){
  2. //Iftheactivitybeinglaunchedisthesameastheonecurrently
  3. //atthetop,thenweneedtocheckifitshouldonlybelaunched
  4. //once.
  5. ActivityRecordtop=topRunningNonDelayedActivityLocked(notTop);
  6. if(top!= null&&r.resultTo== null){
  7. if(top.realActivity.equals(r.realActivity)){
  8. ......
  9. }
  10. }
  11. }
这段代码的逻辑是看一下,当前在堆栈顶端的Activity是否就是即将要启动的Activity,有些情况下,如果即将要启动的Activity就在堆栈的顶端,那么,就不会重新启动这个Activity的别一个实例了,具体可以参考官方网站 http://developer.android.com/reference/android/content/pm/ActivityInfo.html 。现在处理堆栈顶端的Activity是Launcher,与我们即将要启动的MainActivity不是同一个Activity,因此,这里不用进一步处理上述介绍的情况。 执行到这里,我们知道,要在一个新的Task里面来启动这个Activity了,于是新创建一个Task:
        
  1. if(r.resultTo== null&&!addingToTask
  2. &&(launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK)!= 0){
  3. //todo:shoulddobettermanagementofintegers.
  4. mService.mCurTask++;
  5. if(mService.mCurTask<= 0){
  6. mService.mCurTask= 1;
  7. }
  8. r.task= newTaskRecord(mService.mCurTask,r.info,intent,
  9. (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH)!= 0);
  10. ......
  11. newTask= true;
  12. if(mMainStack){
  13. mService.addRecentTaskLocked(r.task);
  14. }
  15. }
新建的Task保存在r.task域中,同时,添加到mService中去,这里的mService就是ActivityManagerService了。 最后就进入startActivityLocked(r, newTask, doResume)进一步处理了。这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
        
  1. public classActivityStack{
  2. ......
  3. private final voidstartActivityLocked(ActivityRecordr, booleannewTask,
  4. booleandoResume){
  5. final intNH=mHistory.size();
  6. intaddPos=- 1;
  7. if(!newTask){
  8. ......
  9. }
  10. //Placeanewactivityattopofstack,soitisnexttointeract
  11. //withtheuser.
  12. if(addPos< 0){
  13. addPos=NH;
  14. }
  15. //Ifwearenotplacingthenewactivityfrontmost,wedonotwant
  16. //todelivertheonUserLeavingcallbacktotheactualfrontmost
  17. //activity
  18. if(addPos<NH){
  19. ......
  20. }
  21. //Slottheactivityintothehistorystackandproceed
  22. mHistory.add(addPos,r);
  23. r.inHistory= true;
  24. r.frontOfTask=newTask;
  25. r.task.numActivities++;
  26. if(NH> 0){
  27. //Wewanttoshowthestartingpreviewwindowifweare
  28. //switchingtoanewtask,orthenextactivity'sprocessis
  29. //notcurrentlyrunning.
  30. ......
  31. } else{
  32. //Ifthisisthefirstactivity,don'tdoanyfancyanimations,
  33. //becausethereisnothingforittoanimateontopof.
  34. ......
  35. }
  36. ......
  37. if(doResume){
  38. resumeTopActivityLocked( null);
  39. }
  40. }
  41. ......
  42. }
这里的NH表示当前系统中历史任务的个数,这里肯定是大于0,因为Launcher已经跑起来了。当NH>0时,并且现在要切换新任务时,要做一些任务切的界面操作,这段代码我们就不看了,这里不会影响到下面启Activity的过程,有兴趣的读取可以自己研究一下。 这里传进来的参数doResume为true,于是调用resumeTopActivityLocked进一步操作。 Step 10. Activity.resumeTopActivityLocked 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
        
  1. public classActivityStack{
  2. ......
  3. /**
  4. *Ensurethatthetopactivityinthestackisresumed.
  5. *
  6. *@paramprevThepreviouslyresumedactivity,forwhenintheprocess
  7. *ofpausing;canbenulltocallfromelsewhere.
  8. *
  9. *@returnReturnstrueifsomethingisbeingresumed,orfalseif
  10. *nothinghappened.
  11. */
  12. final booleanresumeTopActivityLocked(ActivityRecordprev){
  13. //Findthefirstactivitythatisnotfinishing.
  14. ActivityRecordnext=topRunningActivityLocked( null);
  15. //Rememberhowwe'llprocessthispause/resumesituation,andensure
  16. //thatthestateisresethoweverwewindupproceeding.
  17. final booleanuserLeaving=mUserLeaving;
  18. mUserLeaving= false;
  19. if(next== null){
  20. ......
  21. }
  22. next.delayedResume= false;
  23. //Ifthetopactivityistheresumedone,nothingtodo.
  24. if(mResumedActivity==next&&next.state==ActivityState.RESUMED){
  25. ......
  26. }
  27. //Ifwearesleeping,andthereisnoresumedactivity,andthetop
  28. //activityispaused,wellthatisthestatewewant.
  29. if((mService.mSleeping||mService.mShuttingDown)
  30. &&mLastPausedActivity==next&&next.state==ActivityState.PAUSED){
  31. ......
  32. }
  33. ......
  34. //Ifwearecurrentlypausinganactivity,thendon'tdoanything
  35. //untilthatisdone.
  36. if(mPausingActivity!= null){
  37. ......
  38. }
  39. ......
  40. //Weneedtostartpausingthecurrentactivitysothetopone
  41. //canberesumed...
  42. if(mResumedActivity!= null){
  43. ......
  44. startPausingLocked(userLeaving, false);
  45. return true;
  46. }
  47. ......
  48. }
  49. ......
  50. }
函数先通过调用topRunningActivityLocked函数获得堆栈顶端的Activity,这里就是MainActivity了,这是在上面的Step 9设置好的,保存在next变量中。 接下来把mUserLeaving的保存在本地变量userLeaving中,然后重新设置为false,在上面的Step 9中,mUserLeaving的值为true,因此,这里的userLeaving为true。 这里的mResumedActivity为Launcher,因为Launcher是当前正被执行的Activity。 当我们处理休眠状态时,mLastPausedActivity保存堆栈顶端的Activity,因为当前不是休眠状态,所以mLastPausedActivity为null。 有了这些信息之后,下面的语句就容易理解了:
        
  1. //Ifthetopactivityistheresumedone,nothingtodo.
  2. if(mResumedActivity==next&&next.state==ActivityState.RESUMED){
  3. ......
  4. }
  5. //Ifwearesleeping,andthereisnoresumedactivity,andthetop
  6. //activityispaused,wellthatisthestatewewant.
  7. if((mService.mSleeping||mService.mShuttingDown)
  8. &&mLastPausedActivity==next&&next.state==ActivityState.PAUSED){
  9. ......
  10. }
它首先看要启动的Activity是否就是当前处理Resumed状态的Activity,如果是的话,那就什么都不用做,直接返回就可以了;否则再看一下系统当前是否休眠状态,如果是的话,再看看要启动的Activity是否就是当前处于堆栈顶端的Activity,如果是的话,也是什么都不用做。 上面两个条件都不满足,因此,在继续往下执行之前,首先要把当处于Resumed状态的Activity推入Paused状态,然后才可以启动新的Activity。但是在将当前这个Resumed状态的Activity推入Paused状态之前,首先要看一下当前是否有Activity正在进入Pausing状态,如果有的话,当前这个Resumed状态的Activity就要稍后才能进入Paused状态了,这样就保证了所有需要进入Paused状态的Activity串行处理。 这里没有处于Pausing状态的Activity,即mPausingActivity为null,而且mResumedActivity也不为null,于是就调用startPausingLocked函数把Launcher推入Paused状态去了。 Step 11. ActivityStack.startPausingLocked 这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityStack.java文件中:
        
  1. public classActivityStack{
  2. ......
  3. private final voidstartPausingLocked( booleanuserLeaving, booleanuiSleeping){
  4. if(mPausingActivity!= null){
  5. ......
  6. }
  7. ActivityRecordprev=mResumedActivity;
  8. if(prev== null){
  9. ......
  10. }
  11. ......
  12. mResumedActivity= null;
  13. mPausingActivity=prev;
  14. mLastPausedActivity=prev;
  15. prev.state=ActivityState.PAUSING;
  16. ......
  17. if(prev.app!= null&&prev.app.thread!= null){
  18. ......
  19. try{
  20. ......
  21. prev.app.thread.schedulePauseActivity(prev,prev.finishing,userLeaving,
  22. prev.configChangeFlags);
  23. ......
  24. } catch(Exceptione){
  25. ......
  26. }
  27. } else{
  28. ......
  29. }
  30. ......
  31. }
  32. ......
  33. }
函数首先把mResumedActivity保存在本地变量prev中。在上一步Step 10中,说到mResumedActivity就是Launcher,因此,这里把Launcher进程中的ApplicationThread对象取出来,通过它来通知Launcher这个Activity它要进入Paused状态了。当然,这里的prev.app.thread是一个ApplicationThread对象的远程接口,通过调用这个远程接口的schedulePauseActivity来通知Launcher进入Paused状态。 参数prev.finishing表示prev所代表的Activity是否正在等待结束的Activity列表中,由于Laucher这个Activity还没结束,所以这里为false;参数prev.configChangeFlags表示哪些config发生了变化,这里我们不关心它的值。 Step 12.ApplicationThreadProxy.schedulePauseActivity 这个函数定义在frameworks/base/core/java/android/app/ApplicationThreadNative.java文件中:
        
  1. classApplicationThreadProxy implementsIApplicationThread{
  2. ......
  3. public final voidschedulePauseActivity(IBindertoken, booleanfinished,
  4. booleanuserLeaving, intconfigChanges) throwsRemoteException{
  5. Parceldata=Parcel.obtain();
  6. data.writeInterfaceToken(IApplicationThread.descriptor);
  7. data.writeStrongBinder(token);
  8. data.writeInt(finished? 1: 0);
  9. data.writeInt(userLeaving? 1: 0);
  10. data.writeInt(configChanges);
  11. mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION,data, null,
  12. IBinder.FLAG_ONEWAY);
  13. data.recycle();
  14. }
  15. ......
  16. }
这个函数通过Binder进程间通信机制进入到ApplicationThread.schedulePauseActivity函数中。 Step 13. ApplicationThread.schedulePauseActivity 这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中,它是ActivityThread的内部类:
        
  1. public final classActivityThread{
  2. ......
  3. private final classApplicationThread extendsApplicationThreadNative{
  4. ......
  5. public final voidschedulePauseActivity(IBindertoken, booleanfinished,
  6. booleanuserLeaving, intconfigChanges){
  7. queueOrSendMessage(
  8. finished?H.PAUSE_ACTIVITY_FINISHING:H.PAUSE_ACTIVITY,
  9. token,
  10. (userLeaving? 1: 0),
  11. configChanges);
  12. }
  13. ......
  14. }
  15. ......
  16. }
这里调用的函数queueOrSendMessage是ActivityThread类的成员函数。 上面说到,这里的finished值为false,因此,queueOrSendMessage的第一个参数值为H.PAUSE_ACTIVITY,表示要暂停token所代表的Activity,即Launcher。 Step 14. ActivityThread.queueOrSendMessage 这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
        
  1. public final classActivityThread{
  2. ......
  3. private final voidqueueOrSendMessage( intwhat,Objectobj, intarg1){
  4. queueOrSendMessage(what,obj,arg1, 0);
  5. }
  6. private final voidqueueOrSendMessage( intwhat,Objectobj, intarg1, intarg2){
  7. synchronized( this){
  8. ......
  9. Messagemsg=Message.obtain();
  10. msg.what=what;
  11. msg.obj=obj;
  12. msg.arg1=arg1;
  13. msg.arg2=arg2;
  14. mH.sendMessage(msg);
  15. }
  16. }
  17. ......
  18. }
这里首先将相关信息组装成一个msg,然后通过mH成员变量发送出去,mH的类型是H,继承于Handler类,是ActivityThread的内部类,因此,这个消息最后由H.handleMessage来处理。 Step 15. H.handleMessage 这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
        
  1. public final classActivityThread{
  2. ......
  3. private final classH extendsHandler{
  4. ......
  5. public voidhandleMessage(Messagemsg){
  6. ......
  7. switch(msg.what){
  8. ......
  9. casePAUSE_ACTIVITY:
  10. handlePauseActivity((IBinder)msg.obj, false,msg.arg1!= 0,msg.arg2);
  11. maybeSnapshot();
  12. break;
  13. ......
  14. }
  15. ......
  16. }
  17. ......
  18. }
这里调用ActivityThread.handlePauseActivity进一步操作,msg.obj是一个ActivityRecord对象的引用,它代表的是Launcher这个Activity。

更多相关文章

  1. C语言函数以及函数的使用
  2. Android 隐藏系统状态栏和标题栏
  3. Android App 隐藏显示标题栏、状态栏、导航栏
  4. Android 蓝牙状态机以及蓝牙启动状态机
  5. Android中获取屏幕相关信息(屏幕大小,状态栏、标题栏高度)
  6. 获取Android设备电池电量状态
  7. Android 5.1系统禁止通知状态栏下拉
  8. Android 获取状态栏的高度
  9. Android 沉浸式状态栏实现,以及遇到的问题

随机推荐

  1. Android第三十三期 - Dialog的应用
  2. Android提高第十九篇之"多方向"抽屉
  3. Android中文API(125) ―― VideoView
  4. Android控件-多选按钮、单选按钮
  5. Android中使用jdbc连接Sqllite
  6. android延迟执行任务(刷新按钮旋转)
  7. Android:Eclipse+ADT+Android SDK 搭建安
  8. “刨根问底”之Android(安卓)消息机制
  9. Android ActionBarSherlock的使用
  10. 打开电话Android系统调用