activity的启动模式,startactivity的过程

灰太狼 2022-06-08 14:55 332阅读 0赞

Android:launchMode

用于指定Activity被启动的方式,主要包括两个方面:即Activity是否为单实例,及Activity归属的task。不管是那种方式,被启动的Activity都要位于Activitytask的栈顶。

1),standard,默认状态,这种模式下Activity是多实例的,系统总是启动一个新的Activity来满足要求,即使之前已经存在这个Activity的实例;并且它归属于调用startactivity将其启动那个task(除非intent明确指明FLAG_ACTIVITY_NEW_TASK,这样就跟singleTask的启动模式是一样的)。

2),singletop,这个跟standard模式非常类似,它也表明Activity是多实例(下面是例外的情况)的,且task的归属也一致。区别是:

对于standard,无论何时它都会生成一个新的Activity实例;而singleTop当遇到目标Activity已经存在与目标task的栈顶时,会将Intent通过onNewIntent传给这个Activity而不是生成一个新的实例。

3),singleTask,它表明这个Activity是单实例的,Intent将通过OnNewIntent传送给已有的实例;而且他总是在一个新的task中启动。这种类型的Activity永远在task的根位置。另外,singleTask允许其他的Activity进驻到它所在的task中,这一点跟singleInstance不同。

4),singleInstance,和singleTask基本一致,不过它不允许其他的Activity进驻到它所属的task中,也就是说,singleInstance永远都是在一个孤立的task中。

  1. Activity的生命周期
  2. 一个activity的启动:
  3. 10-26 22:18:23.365 24691-24691/? D/First-Activity: recycle,,onCreate
  4. 10-26 22:18:23.365 24691-24691/? D/First-Activity: recycle,,onStart
  5. 10-26 22:18:23.367 24691-24691/? D/First-Activity: recycle,,onResume
  6. back键,让activity的退出,activity会被出栈(Activitystack):
  7. com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onPause
  8. com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onStop
  9. com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onDestroy
  10. home间,让activity退出,会执行onPause(),onStop(),但是不会执行onDestory(),
  11. 启动另一个activity
  12. com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onPause
  13. com.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onCreate
  14. com.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onStart
  15. com.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onResume
  16. com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onStop
  17. 从第二个activity返回:
  18. com.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onPause
  19. com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onRestart
  20. com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onStart
  21. com.firstapp.linjw.myapplication_n D/First-Activity: recycle,,onResume
  22. com.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onStop
  23. com.firstapp.linjw.myapplication_n D/Second-Activity: recycle,,onDestroy
  24. 1ActivityManagerService的功能,ActivityManagerService的功能

1)组件状态的管理,四个组件的开启、关闭等一系列操作

2)组件状态查询**,查询组件当前的运行情况**

3)Task相关的操作**removeTask**movetasktofront。

4)其他一些系统运行信息的查询**getMemeoryInfo等。**

AMS是在systemserver中启动的**。**

  1. SystemServer.java
  2. private void startBootstrapServices() {
  3. //这里会调用AMS的start方法。
  4. mActivityManagerService = mSystemServiceManager.startService(
  5. ActivityManagerService.Lifecycle.class).getService();
  6. //然后,进行初始化,并把一些服务添加到serviceManager中。
  7. mActivityManagerService.initPowerManagement();
  8. mActivityManagerService.setSystemProcess();
  9. mActivityManagerService.installSystemProviders();
  10. mActivityManagerService.setWindowManager(wm);
  11. mActivityManagerService.enterSafeMode();
  12. //将一系列与进程管理相关的服务,注册到systemmanager。
  13. mActivityManagerService.setSystemProcess();
  14. //下面这个调用会先执行AMS中的systemready方法,确保AMS启动ok了,才会执行这个回调,在这个回调中,systemserver接着执行系统服务的启动,在这里启动systemUI。
  15. mActivityManagerService.systemReady(new Runnable() {
  16. public void run() {
  17. mSystemServiceManager.startBootPhase(
  18. SystemService.PHASE_ACTIVITY_MANAGER_READY);
  19. mActivityManagerService.startObservingNativeCrashes();
  20. startSystemUi(context);
  21. mSystemServiceManager.startBootPhase(
  22. SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
  23. }
  24. });
  25. }
  26. ActivityManagerService.java
  27. public void systemReady(final Runnable goingCallback) {
  28. //在AMS启动完成之前, mSystemReady是false的,
  29. synchronized(this) {
  30. if (mSystemReady) {
  31. goingCallback.run();
  32. return;
  33. }
  34. mSystemReady = true;
  35. }
  36. //下面是AMS的启动操作,包括启动home应用程序。
  37. retrieveSettings();
  38. readGrantedUriPermissionsLocked();
  39. //这里去执行systemserver中的回调,继续systemserver中未完成的系统服务的启动。因为systemserver的后续运行要依赖AMS,所以在AMS还没就绪的情况下就冒然返回,可能造成系统宕机。
  40. if (goingCallback != null) goingCallback.run();
  41. ...
  42. startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
  43. startHomeActivityLocked(currentUserId, "systemReady");
  44. mStackSupervisor.resumeFocusedStackTopActivityLocked();
  45. }

启动时,通过Lifecycle这个Systemservice先创建ActivityManagerService实例,然后调用其start方法。

在AMS的构造函数中,会创建一个线程ServiceThread,这是一个自带消息队列的线程。

  1. ActivityManagerService,一个用于管理Activity(其他组件)运行状态的系统进程。
  2. AMS会向servicemanager登记多种Binderserver,如:activitymeminfocpuinfoprocessinfopermission等。
  3. public void setSystemProcess() @ActivityManagerService.java{
  4. ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
  5. ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
  6. ServiceManager.addService("meminfo", new MemBinder(this));
  7. ServiceManager.addService("cpuinfo", new CpuBinder(this));
  8. ServiceManager.addService("processinfo", new ProcessInfoService(this));
  9. ServiceManager.addService("permission", new PermissionController(this));
  10. }
  11. 2,管理当前系统中的Activity状态。
  12. Activitystack是管理系统中所有Activity状态的一个数据结构。一个Activity所经历的状态有:
  13. enum ActivityState {
  14. INITIALIZING,//正在初始化
  15. RESUMED,//恢复
  16. PAUSING,//正在暂停
  17. PAUSED,//已经暂停
  18. STOPPING,//正在停止
  19. STOPPED,//已经停止
  20. FINISHING,//正在完成
  21. DESTROYING,//正在销毁
  22. DESTROYED//已经销毁
  23. }
  24. Activity的状态迁移图:的状态迁移图:

Center

  1. 2.1 AMS主要的变量
  2. ActivityManagerService.java
  3. AMS通过ActivityStackSupervisor mStackSupervisor管理系统的Activitystack,通过StackSupervisor运行所有的activitystacks
  4. ActivityRecord mFocusedActivity;//当前拥有焦点的Activity。
  5. RecentTasks mRecentTasks;//用于启动最近任务的intent列表。
  6. ActivityStackSupervisor.java
  7. ActivityStack mHomeStack;//包含launcher app的stack,
  8. ActivityStack mFocusedStack;//当前可以接收输入事件或启动下一个Activity的stack。
  9. //等待即将可见的新的Activity的列表。
  10. ArrayList<ActivityRecord> mWaitingVisibleActivities
  11. //列表中的Activity可以被stop,但是要等待下一个Activity就绪。
  12. ArrayList<ActivityRecord> mStoppingActivities
  13. //列表中Activity可以被finish的,但是要等上一个Activity就绪。
  14. ArrayList<ActivityRecord> mFinishingActivities
  15. ActivityStack.java
  16. //所有前面Activity的回退记录,包括可能正在运行的Activity。
  17. ArrayList<TaskRecord> mTaskHistory
  18. //正在运行的Activity的列表,以最近的使用情况排序,第一个是最近最少使用的元素。
  19. ArrayList<ActivityRecord> mLRUActivities
  20. //当前正在被暂停的Activity
  21. ActivityRecord mPausingActivity
  22. //上一个被暂停的Activity
  23. ActivityRecord mLastPausedActivity
  24. //当前被恢复的Activity
  25. ActivityRecord mResumedActivity
  26. //最近一次被启动的Activity
  27. ActivityRecord mLastStartedActivity
  28. TaskRecord.java
  29. //task中的所有的Activity,这个task是在历史记录中按顺序排列的
  30. ArrayList<ActivityRecord> mActivities;
  31. //当前的stack,管理者这个task中的Activity。
  32. ActivityStack stack;
  33. ActivityRecord.java
  34. //表明这个Activity所属的task,
  35. TaskRecord task;
  36. 大致结构:
  37. mStackSupervisorActivityStackSupervisor)负责管理所有的Activitystack
  38. ActivityStack管理着系统中的task,也就是TaskRecord
  39. TaskRecord中的mActivities中保存了属于当前taskActivitysActivityRecord),这些Activity在是以stack的形式存放的,每一个Activity就是一个Activityrecord
  40. 从获取顶层Activity的函数可以看出以上关系:
  41. final ActivityRecord topRunningActivityLocked()@ActivityStack.java{
  42. for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
  43. ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked();
  44. }
  45. }
  46. ActivityRecord topRunningActivityLocked()@TaskRecord.java{
  47. for (int activityNdx = mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
  48. ActivityRecord r = mActivities.get(activityNdx);
  49. if (!r.finishing && stack.okToShowLocked(r)) {
  50. return r;
  51. }
  52. }
  53. }

因为Task是有先后之分的,所以对ActivityRecord的存储使用的是stack栈的方式,具体可以参考addActivityAtBottom()@TaskRecord.java,addActivityToTop()@TaskRecord.java

  1. 3startActivity的过程
  2. 直接从AMS说起:
  3. public final int startActivity(IApplicationThread caller, String callingPackage,
  4. Intent intent, String resolvedType, IBinder resultTo, String resultWho, int
  5. requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
  6. return startActivityAsUser(caller, callingPackage, intent, resolvedType,
  7. resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
  8. UserHandle.getCallingUserId());
  9. }
  10. 通过UserHandle.getCallingUserId()获取调用者的用户ID
  11. //下面主要权限检查
  12. public final int startActivityAsUser(...){
  13. //调用者是否属于被隔离的对象。
  14. enforceNotIsolatedCaller("startActivity");
  15. //调用者是否有权限执行这一操作。
  16. userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
  17. Binder.getCallingUid(),userId, false, ALLOW_FULL_ONLY, "startActivity",
  18. null);
  19. return mActivityStarter.startActivityMayWait(…);
  20. }
  21. final int startActivityMayWait(...)@ActivityStarter.java{
  22. //通过解析intent,确定目标Activity。
  23. ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
  24. ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
  25. profilerInfo);
  26. //判断目标Activity所属进程,是不是重量级进程,对于重量级进程不参与正常的应用程序的生命周期。所以如果系统中已经存在的重量级进程不是即将要启动的这个,那么要给intent重新赋值,重新解析。
  27. if (aInfo.applicationInfo.privateFlags&
  28. ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
  29. if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
  30. final ProcessRecord heavy = mService.mHeavyWeightProcess;
  31. if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid
  32. || !heavy.processName.equals(aInfo.processName))) {
  33. Intent newIntent = new Intent();
  34. newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,
  35. new IntentSender(target));
  36. newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,
  37. aInfo.packageName);
  38. newIntent.setClassName("android",
  39. HeavyWeightSwitcherActivity.class.getName());
  40. intent = newIntent;
  41. rInfo = mSupervisor.resolveIntent(intent, null /*resolvedType*/,
  42. userId);
  43. }
  44. }
  45. //调用 startActivityLocked进一步执行启动操作。这个 startActivityLocked函数参数较多,后面还有调用同名的 startActivityLocked函数,它的参数较少。
  46. int res = startActivityLocked(…);
  47. }
  48. final int startActivityLocked(...)@ActivityStarter.java{
  49. //确保调用者本身的进程是存在的,否则返回 PERMISSION_DENIED,权限被拒绝错误。
  50. ProcessRecord callerApp = null;
  51. callerApp = mService.getRecordForAppLocked(caller);
  52. if (callerApp != null) {
  53. callingPid = callerApp.pid;
  54. callingUid = callerApp.info.uid;
  55. }else{
  56. err = ActivityManager.START_PERMISSION_DENIED;
  57. }
  58. //处理标记: FLAG_ACTIVITY_FORWARD_RESULT,即Activity_result的跨越式传递。
  59. if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
  60. && sourceRecord != null) {
  61. resultWho = sourceRecord.resultWho;
  62. }
  63. //再次对调用者做权限检查,包括是否匹配intent-filter规则。
  64. boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo,
  65. resultWho,requestCode, callingPid, callingUid, callingPackage,…);
  66. abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
  67. callingPid, resolvedType, aInfo.applicationInfo);
  68. //生成一个ActivityRecord,记录各项判断结果。
  69. ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid,
  70. callingPackage,…);
  71. //调用 startActivityUnchecked,处理启动模式,及intent标志相关的。
  72. err = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
  73. startFlags,true, options, inTask);
  74. }
  75. //对一系列启动标志的处理。对一系列启动标志的处理。
  76. private int startActivityUnchecked(...){
  77. //获取intent中的启动标记。
  78. final Intent baseIntent = mInTask.getBaseIntent();
  79. mLaunchFlags = mLaunchFlags |baseIntent.getFlags();
  80. //如果被启动的对象和调用者是同一个,什么都不用做,只要正确恢复顶层的Activity。
  81. if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
  82. resumeTargetStackIfNeeded();
  83. return START_RETURN_INTENT_TO_CALLER;
  84. }
  85. //要启动的是newtask,相关的处理。
  86. if(mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0){
  87. newTask = true;
  88. setTaskFromReuseOrCreateNewTask(taskToAffiliate);
  89. }
  90. //接着调用另一个startActivityLocked。
  91. mTargetStack.startActivityLocked(mStartActivity, newTask,
  92. mKeepCurTransition, mOptions);
  93. //恢复最上层的Activity。
  94. mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack,
  95. mStartActivity,mOptions);
  96. }
  97. //这是启动Activity的最后一步了。
  98. final void startActivityLocked(){
  99. //如果目标Activity不在新的task中启动,就要找到他属于那个已存在的task,通过遍历整个 mTaskHistory列表,如果整个task对用户还不可见,先把Activity加进去,并把它加到history队列中。addConfigOverride(r, task);这句调用是在WindowManagerservice中做好注册,也就是添加一个AppWindowToken,
  100. if (!newTask) {
  101. for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
  102. task = mTaskHistory.get(taskNdx);
  103. if (task == r.task) {
  104. task.addActivityToTop(r);
  105. r.putInHistory();
  106. addConfigOverride(r, task);
  107. }
  108. }
  109. }
  110. //是否显示启动窗口。
  111. if (SHOW_APP_STARTING_PREVIEW && doShow) {
  112. ActivityRecord prev =
  113. r.task.topRunningActivityWithStartingWindowLocked();
  114. r.showStartingWindow(prev, showStartingIcon);
  115. }
  116. }
  117. 到这里startActivity的一系列调用就分析完了,接下来就是恢复最顶层的Activity
  118. boolean resumeFocusedStackTopActivityLocked(
  119. ActivityStack targetStack, ActivityRecord target, ActivityOptions
  120. targetOptions)@ActivityStackSupervisor.java {
  121. targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
  122. result = resumeTopActivityInnerLocked(prev, options);
  123. }
  124. private boolean resumeTopActivityInnerLocked(ActivityRecord prev,
  125. ActivityOptions options) {
  126. //取出最上面有效的Activity。
  127. final ActivityRecord next = topRunningActivityLocked();
  128. //next为null,启动launcher界面。
  129. if (next == null) {
  130. return isOnHomeDisplay() &&
  131. mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
  132. }
  133. //如果正在运行的Activity就是目标对象,就不用重复启动了。
  134. if (mResumedActivity == next && next.state == ActivityState.RESUMED){
  135. return false;
  136. }
  137. //如果目标Activity正在等待停止,就是正在stoping,那么就终止这个操作,从一下列表中移除,并置sleeping标志为false。
  138. mStackSupervisor.mStoppingActivities.remove(next);
  139. mStackSupervisor.mGoingToSleepActivities.remove(next);
  140. next.sleeping = false;
  141. mStackSupervisor.mWaitingVisibleActivities.remove(next);
  142. //mResumedActivity不为null,说明前一个Activity还在运行,先执行pause操作。
  143. if (mResumedActivity != null) {
  144. pausing |= startPausingLocked(userLeaving, false, next,
  145. dontWaitForPause);
  146. }
  147. //在启动新的Activity之前,要把前一个窗口隐藏掉。这个操作只在前一个Activity正在finishing时执行,这就意味着它处于正在resumed的Activity的上面,所以要把它尽快隐藏,也就是说是否要隐藏前一个取决于新的Activity是不是全屏显示。
  148. if (prev != null && prev != next) {
  149. if (prev.finishing) {
  150. mWindowManager.setAppVisibility(prev.appToken, false);
  151. }
  152. }
  153. //正式启动目标Activity,目标进程已有实例存在,告知目标线程resume指定的Activity,这个函数 scheduleResumeActivity会叫起Activity的onResume方法。
  154. if (next.app != null && next.app.thread != null) {
  155. mWindowManager.setAppVisibility(next.appToken, true);
  156. next.app.thread.scheduleResumeActivity(next.appToken,
  157. next.app.repProcState,mService.isNextTransitionForward(),
  158. resumeAnimOptions);
  159. }else{
  160. //目标Activity所属程序还没进程在运行,启动目标进程。
  161. mStackSupervisor.startSpecificActivityLocked(next, true, true);
  162. }
  163. }
  164. // startSpecificActivityLocked最后会调用Process.start()启动一个进程,同时加载了 ActivityThread这一主线程。
  165. private final void startProcessLocked(...)@ActivityManagerService.java{
  166. entryPoint = "android.app.ActivityThread";
  167. Process.ProcessStartResult startResult = Process.start(entryPoint,
  168. app.processName, uid, uid, gids, debugFlags, mountExternal,
  169. app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
  170. app.info.dataDir, entryPointArgs);
  171. }
  172. //目标进程启动后,会通过 attachApplication回调AMS,
  173. private void attach(boolean system)@ActivityThread.java {
  174. final IActivityManager mgr = ActivityManagerNative.getDefault();
  175. mgr.attachApplication(mAppThread);
  176. }
  177. //AMS在接收回调后,会判断当前是否有Activity等待这个进程的启动,如果有,就调用 realStartActivityLocked继续之前的启动
  178. 操作,接下来就是Activity生命周期的开始。
  179. private final boolean attachApplicationLocked()@ActivityManagerService.java{
  180. mStackSupervisor.attachApplicationLocked(app);
  181. }
  182. boolean attachApplicationLocked(ProcessRecord app)@ActivityStackSupervisor.java{
  183. realStartActivityLocked(hr, app, true, true);
  184. }
  185. final boolean realStartActivityLocked()@ActivityStackSupervisor.java{
  186. app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,…);
  187. }

发表评论

表情:
评论列表 (有 0 条评论,332人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Activity启动模式

    今天我们来讲的是Activity有几种启动模式,其实以前我没太在意这方面的知识,但是我在开发过程中发现,其实了解和学习这几种启动模式还是非常重要的,确实能用到。那么接下来我们就

    相关 Activity启动模式

    在Android程序中,应用程序通过活动栈来管理Activity,活动栈中有多少个Activity对象,我们在退出程序的时候就要按多少下返回键(即要将活动栈中的所有Activi