由于Activity在8.0上相比较之前的代码,有一些差异,所有特写此文记录一下
根Activity组件是由 Launcher组件来启动的, 而Launcher组件又是通过 Activity管理服务 ActivityManagerService来启动根Activity组件的。由于根Activity组件、 Launcher组件和ActivityManagerService是分别运行在不同的进程中的, 因此, 根Activity组件的启动过程就涉及到了三个进程。 这三个进程是通过Binder进程间通信机制来完成根Activity组件的启动过程的。
8.0之前的版本:
Launcher组件启动根Activity组件的过程如下所示。
(1) Launcher组件向ActivityManagerService发送一个启动根Activity组件的进程间通信请求。
(2) ActivityManagerService首先将要启动的根Activity组件的信息保存下来, 然后再向 Launcher组件发送一个进入中止状态的进程间通信请求。
(3) Launcher组件进入到中止状态之后, 就会向 ActivityManagerService发送一个已进入中止状态的进程间通信请求, 以便ActivityManagerService可以继续执行启动根Activity组件的操作。
(4) ActivityManagerService发现用来运行根Activity组件的应用程序进程不存在,因此, 它就会先启动一个新的应用程序进程。
(5) 新的应用程序进程启动完成之后, 就会向ActivityManagerService发送一个启动完成的进程间 通信请求,以便ActivityManagerService可以继续执行启动根Activity组件的操作。
(6) ActivityManagerService将第2步保存下来的根Activity组件的信息发送给第4步创建的应用程序进程,以便它可以将根Activity组件启动起来。
Android-8.0.0-r4 分别是Launcher请求AMS过程、 AMS到ApplicationThread的调用过程和ActivityThread启动Activity
一、Launcher请求AMS过程
1.Launcher.startActivitySafely
代码路径:/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
(http://androidxref.com/8.0.0_r4/xref/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java)
2704 public boolean startActivitySafely(View v, Intent intent, ItemInfo item) { ................................ 2718 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2719 if (v != null) { 2720 intent.setSourceBounds(getViewBounds(v)); 2721 } 2722 try {
.................................. 2732 startActivity(intent, optsBundle); 2733 } else { 2734 LauncherAppsCompat.getInstance(this).startActivityForProfile( 2735 intent.getComponent(), user, intent.getSourceBounds(), optsBundle); 2736 } 2737 return true; 2738 } catch (ActivityNotFoundException|SecurityException e) { 2739 Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); 2740 Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e); 2741 } 2742 return false; 2743 }
在2718行设置Flag为Intent.FLAG_ACTIVITY_NEW_TASK,这样根Activity会在新的任务栈中启动。
在2732行会调用startActivity方法,这个startActivity方法的实现在framework层提供的接口Activity中
2.Activity.startActivity
代码路径:/frameworks/base/core/java/android/app/Activity.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/Activity.java)
4784 @Override 4785 public void startActivity(Intent intent, @Nullable Bundle options) { 4786 if (options != null) { 4787 startActivityForResult(intent, -1, options); 4788 } else { 4789 // Note we want to go through this call for compatibility with 4790 // applications that may have overridden the method. 4791 startActivityForResult(intent, -1); 4792 } 4793 }
在startActivity方法中会调用startActivityForResult方法,它的第二个参数为-1,表示Launcher不需要知道Activity启动的结果
3.Activity.startActivityForResult
代码路径:/frameworks/base/core/java/android/app/Activity.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/Activity.java)
4467 public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, 4468 @Nullable Bundle options) { 4469 if (mParent == null) { 4470 options = transferSpringboardActivityOptions(options); 4471 Instrumentation.ActivityResult ar = 4472 mInstrumentation.execStartActivity( 4473 this, mMainThread.getApplicationThread(), mToken, this, 4474 intent, requestCode, options); 4475 if (ar != null) { 4476 mMainThread.sendActivityResult( 4477 mToken, mEmbeddedID, requestCode, ar.getResultCode(), 4478 ar.getResultData()); 4479 }
.............................................. 4501 } 4502 }
在4469行的mParent是Activity类型的,表示当前Activity的父类。因为目前根Activity还没有创建出来,因此,mParent == null成立。接着调用Instrumentation的execStartActivity方法,Instrumentation主要用来监控应用程序和系统的交互,execStartActivity方法的代码
4.Instrumentation.execStartActivity
代码路径:/frameworks/base/core/java/android/app/Instrumentation.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/Instrumentation.java)
1713 */ 1714 public ActivityResult execStartActivity( 1715 Context who, IBinder contextThread, IBinder token, String target, 1716 Intent intent, int requestCode, Bundle options) { 1717 IApplicationThread whoThread = (IApplicationThread) contextThread; ..................................... 1740 try { 1741 intent.migrateExtraStreamToClipData(); 1742 intent.prepareToLeaveProcess(who); 1743 int result = ActivityManager.getService() 1744 .startActivity(whoThread, who.getBasePackageName(), intent, 1745 intent.resolveTypeIfNeeded(who.getContentResolver()), 1746 token, target, requestCode, 0, null, options); 1747 checkStartActivityResult(result, intent); 1748 } catch (RemoteException e) { 1749 throw new RuntimeException("Failure from system", e); 1750 } 1751 return null; 1752 }
首先在1743行会调用ActivityManager的getService方法来获取AMS的代理对象,接着调用它的startActivity方法。这里与Android 7.0代码的逻辑有些不同,Android 7.0是通过ActivityManagerNative的getDefault来获取AMS的代理对象,现在这个逻辑封装到了ActivityManager中而不是ActivityManagerNative中
5.Instrumentation.getService
代码路径:/frameworks/base/core/java/android/app/Instrumentation.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/Instrumentation.java)4198 */ 4199 public static IActivityManager getService() { 4200 return IActivityManagerSingleton.get(); 4201 } 4202 4203 private static final Singleton<IActivityManager> IActivityManagerSingleton = 4204 new Singleton<IActivityManager>() { 4205 @Override 4206 protected IActivityManager create() { 4207 final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); 4208 final IActivityManager am = IActivityManager.Stub.asInterface(b); 4209 return am; 4210 } 4211 };getService方法调用了IActivityManagerSingleton的get方法,我们接着往下看,IActivityManagerSingleton 是一个Singleton类。
在4207行得到名为”activity”的Service引用,也就是IBinder类型的AMS的引用。
接着在4208行将它转换成IActivityManager类型的对象,这段代码采用的是AIDL,IActivityManager.java类是由AIDL工具在编译时自动生成的,IActivityManager.aidl的文件路径为:frameworks/base/core/java/android/app/IActivityManager.aidl 。要实现进程间通信,服务端也就是AMS只需要继承IActivityManager.Stub类并实现相应的方法就可以了。
注意Android 8.0 之前并没有采用AIDL,而是采用了类似AIDL的形式,用AMS的代理对象ActivityManagerProxy来与AMS进行进程间通信,Android 8.0 去除了ActivityManagerNative的内部类ActivityManagerProxy,代替它的则是IActivityManager,它是AMS在本地的代理。 回到Instrumentation类的execStartActivity方法中,从上面得知execStartActivity方法最终调用的是AMS的startActivity方法。
二、AMS到ApplicationThread的调用过程
6.ActivityManagerService.startActivity
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java)
4460 @Override 4461 public final int startActivity(IApplicationThread caller, String callingPackage, 4462 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4463 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { 4464 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 4465 resultWho, requestCode, startFlags, profilerInfo, bOptions, 4466 UserHandle.getCallingUserId()); 4467 }AMS的startActivity方法中return了startActivityAsUser方法,可以发现startActivityAsUser方法比startActivity方法多了一个参数UserHandle.getCallingUserId(),这个方法会获得调用者的UserId,AMS会根据这个UserId来确定调用者的权限。
7.ActivityManagerService.startActivityAsUser
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java)
4490 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 4491 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 4492 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { 4493 enforceNotIsolatedCaller("startActivity"); 4494 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4495 userId, false, ALLOW_FULL_ONLY, "startActivity", null); 4496 // TODO: Switch to user app stacks here. 4497 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, 4498 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 4499 profilerInfo, null, null, bOptions, false, userId, null, null, 4500 "startActivityAsUser"); 4501 }
在4493行判断调用者进程是否被隔离,如果被隔离则抛出SecurityException异常。
在4494行用于检查调用者是否有权限,如果没有权限也会抛出SecurityException异常。
最后调用了ActivityStarter的startActivityMayWait方法
8.ActivityStarter.startActivityMayWait
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java)
668 final int startActivityMayWait(IApplicationThread caller, int callingUid, 669 String callingPackage, Intent intent, String resolvedType, 670 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 671 IBinder resultTo, String resultWho, int requestCode, int startFlags, 672 ProfilerInfo profilerInfo, WaitResult outResult, 673 Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId, 674 IActivityContainer iContainer, TaskRecord inTask, String reason) { .............................................................. 822 823 final ActivityRecord[] outRecord = new ActivityRecord[1]; 824 int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType, 825 aInfo, rInfo, voiceSession, voiceInteractor, 826 resultTo, resultWho, requestCode, callingPid, 827 callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, 828 options, ignoreTargetSecurity, componentSpecified, outRecord, container, 829 inTask, reason); 830 .................................................... 885 mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, outRecord[0]); 886 return res; 887 } 888 }
ActivityStarter是Android 7.0新加入的类,它是加载Activity的控制类,会收集所有的逻辑来决定如何将Intent和Flags转换为Activity,并将Activity和Task以及Stack相关联。ActivityStarter的startActivityMayWait方法调用了startActivityLocked方法
startActivityLocked方法的参数要比startActivityAsUser多几个,需要注意的是倒数第二个参数类型为TaskRecord,代表启动的Activity所在的栈。最后一个参数”startActivityAsUser”代表启动的理由
9.ActivityStarter.startActivityLocked
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java)
256 int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent, 257 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, 258 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 259 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, 260 String callingPackage, int realCallingPid, int realCallingUid, int startFlags, 261 ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, 262 ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container, 263 TaskRecord inTask, String reason) { 264 265 if (TextUtils.isEmpty(reason)) { 266 throw new IllegalArgumentException("Need to specify a reason."); 267 } 268 mLastStartReason = reason; 269 mLastStartActivityTimeMs = System.currentTimeMillis(); 270 mLastStartActivityRecord[0] = null; 271 272 mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType, 273 aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, 274 callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, 275 options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord, 276 container, inTask); 277 278 if (outActivity != null) { 279 // mLastStartActivityRecord[0] is set in the call to startActivity above. 280 outActivity[0] = mLastStartActivityRecord[0]; 281 } 282 return mLastStartActivityResult; 283 }
在265行判断启动的理由不为空,如果为空则抛出IllegalArgumentException异常。紧接着在272行又调用了startActivity方法
10.ActivityStarter.startActivity
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java)
285 /** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */ 286 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, 287 String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, 288 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 289 IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, 290 String callingPackage, int realCallingPid, int realCallingUid, int startFlags, 291 ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, 292 ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container, 293 TaskRecord inTask) { 294 int err = ActivityManager.START_SUCCESS; 295 // Pull the optional Ephemeral Installer-only bundle out of the options early. 296 final Bundle verificationBundle 297 = options != null ? options.popAppVerificationBundle() : null; 298 299 ProcessRecord callerApp = null; 300 if (caller != null) { 301 callerApp = mService.getRecordForAppLocked(caller); 302 if (callerApp != null) { 303 callingPid = callerApp.pid; 304 callingUid = callerApp.info.uid; 305 } else { 306 Slog.w(TAG, "Unable to find app for caller " + caller 307 + " (pid=" + callingPid + ") when starting: " 308 + intent.toString()); 309 err = ActivityManager.START_PERMISSION_DENIED; 310 } 311 } 312 313
................................ 527 ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid, 528 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(), 529 resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, 530 mSupervisor, container, options, sourceRecord); 531 if (outActivity != null) { 532 outActivity[0] = r; 533 } 534 ................................................. 565 doPendingActivityLaunchesLocked(false); 566 567 return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, 568 options, inTask, outActivity); 569 } 570
ActivityStarter的startActivity方法逻辑比较多,这里列出部分。
在300行判断IApplicationThread类型的caller是否为null,这个caller是方法调用一路传过来的,指向的是Launche进程的ApplicationThread对象。
在527行调用AMS的getRecordForAppLocked方法得到的是代表Launcher进程的callerApp对象,它是ProcessRecord类型的,ProcessRecord用于描述一个应用程序进程。同样的,ActivityRecord用于描述一个Activity,用来记录一个Activity的所有信息。
在527行创建ActivityRecord,这个ActivityRecord用于描述即将要启动的Activity,并在532行将创建的ActivityRecord赋值给ActivityRecord[]类型的outActivity,这个outActivity会作为567行的startActivity方法的参数传递下去。
11.ActivityStarter.startActivity
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java)995 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, 996 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 997 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, 998 ActivityRecord[] outActivity) { 999 int result = START_CANCELED; 1000 try { 1001 mService.mWindowManager.deferSurfaceLayout(); 1002 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, 1003 startFlags, doResume, options, inTask, outActivity); 1004 } finally { 1005 // If we are not able to proceed, disassociate the activity from the task. Leaving an 1006 // activity in an incomplete state can lead to issues, such as performing operations 1007 // without a window container. 1008 if (!ActivityManager.isStartResultSuccessful(result) 1009 && mStartActivity.getTask() != null) { 1010 mStartActivity.getTask().removeActivity(mStartActivity); 1011 } 1012 mService.mWindowManager.continueSurfaceLayout(); 1013 } 1014 1015 postStartActivityProcessing(r, result, mSupervisor.getLastStack().mStackId, mSourceRecord, 1016 mTargetStack); 1017 1018 return result; 1019 }
startActivity方法紧接着调用了startActivityUnchecked方法
12.ActivityStarter.startActivityUnchecked
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java)1021 // Note: This method should only be called from {@link startActivity}. 1022 private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, 1023 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, 1024 int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, 1025 ActivityRecord[] outActivity) { ................................................. 1181 1182 // Should this be considered a new task? 1183 int result = START_SUCCESS; 1184 if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask 1185 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { 1186 newTask = true; 1187 result = setTaskFromReuseOrCreateNewTask( 1188 taskToAffiliate, preferredLaunchStackId, topStack); 1189 } else if (mSourceRecord != null) { 1190 result = setTaskFromSourceRecord(); 1191 } else if (mInTask != null) { 1192 result = setTaskFromInTask(); 1193 } else { 1194 // This not being started from an existing activity, and not part of a new task... 1195 // just put it in the top task, though these days this case should never happen. 1196 setTaskToCurrentTopOrCreateNewTask(); 1197 } 1198 if (result != START_SUCCESS) { 1199 return result; 1200 } ................................................... 1222 if (mDoResume) { 1223 final ActivityRecord topTaskActivity = 1224 mStartActivity.getTask().topRunningActivityLocked(); 1225 if (!mTargetStack.isFocusable() 1226 || (topTaskActivity != null && topTaskActivity.mTaskOverlay 1227 && mStartActivity != topTaskActivity)) { 1228 // If the activity is not focusable, we can't resume it, but still would like to 1229 // make sure it becomes visible as it starts (this will also trigger entry 1230 // animation). An example of this are PIP activities. 1231 // Also, we don't want to resume activities in a task that currently has an overlay 1232 // as the starting activity just needs to be in the visible paused state until the 1233 // over is removed. 1234 mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); 1235 // Go ahead and tell window manager to execute app transition for this activity 1236 // since the app transition will not be triggered through the resume channel. 1237 mWindowManager.executeAppTransition(); 1238 } else { 1239 // If the target stack was not previously focusable (previous top running activity 1240 // on that stack was not visible) then any prior calls to move the stack to the 1241 // will not update the focused stack. If starting the new activity now allows the 1242 // task stack to be focusable, then ensure that we now update the focused stack 1243 // accordingly. 1244 if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) { 1245 mTargetStack.moveToFront("startActivityUnchecked"); 1246 } 1247 mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, 1248 mOptions); 1249 } 1250 } else { 1251 mTargetStack.addRecentActivityLocked(mStartActivity); 1252 } 1253 mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack); 1254 1255 mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredLaunchStackId, 1256 preferredLaunchDisplayId, mTargetStack.mStackId); 1257 1258 return START_SUCCESS; 1259 }
startActivityUnchecked方法主要处理栈管理相关的逻辑。
在1185行,启动根Activity时会将Intent的Flag设置为FLAG_ACTIVITY_NEW_TASK,这样1185行的条件判断就会满足。
接着执行1187行的setTaskFromReuseOrCreateNewTask方法,其内部会创建一个新的TaskRecord,TaskRecord用来描述一个Activity任务栈,也就是说setTaskFromReuseOrCreateNewTask方法内部会创建一个新的Activity任务栈。Activity任务栈其实是一个假想的模型,并不真实的存在。
在1247行会调用ActivityStackSupervisor的resumeFocusedStackTopActivityLocked
13.ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java)
2059 boolean resumeFocusedStackTopActivityLocked( 2060 ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { 2061 if (targetStack != null && isFocusedStack(targetStack)) { 2062 return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); 2063 } 2064 final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); 2065 if (r == null || r.state != RESUMED) { 2066 mFocusedStack.resumeTopActivityUncheckedLocked(null, null); 2067 } else if (r.state == RESUMED) { 2068 // Kick off any lingering app transitions form the MoveTaskToFront operation. 2069 mFocusedStack.executeAppTransition(targetOptions); 2070 } 2071 return false; 2072 } 2073
在2064行调用ActivityStack的topRunningActivityLocked方法获取要启动的Activity所在栈的栈顶的不是处于停止状态的ActivityRecord。
在2065行如果ActivityRecord不为null,或者要启动的Activity的状态不是RESUMED状态,就会调用2066行的ActivityStack的resumeTopActivityUncheckedLocked方法,对于即将要启动的Activity,2065行的条件判断是肯定满足,因此我们来查看ActivityStack的resumeTopActivityUncheckedLocked方法,
14.ActivityStack.resumeTopActivityUncheckedLocked
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java)
2205 boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { 2206 if (mStackSupervisor.inResumeTopActivity) { 2207 // Don't even start recursing. 2208 return false; 2209 } 2210 2211 boolean result = false; 2212 try { 2213 // Protect against recursion. 2214 mStackSupervisor.inResumeTopActivity = true; 2215 result = resumeTopActivityInnerLocked(prev, options); 2216 } finally { 2217 mStackSupervisor.inResumeTopActivity = false; 2218 } 2219 // When resuming the top activity, it may be necessary to pause the top activity (for 2220 // example, returning to the lock screen. We suppress the normal pause logic in 2221 // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the end. 2222 // We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here to ensure 2223 // any necessary pause logic occurs. 2224 mStackSupervisor.checkReadyForSleepLocked(); 2225 2226 return result; 2227 }
紧接着在2215行ActivityStack的resumeTopActivityInnerLocked方法
15.ActivityStack.resumeTopActivityInnerLocked
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java)
2240 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { 2241 if (!mService.mBooting && !mService.mBooted) { 2242 // Not ready yet! 2243 return false; 2244 } 2245 ................................................... 2651 } else { 2652 // Whoops, need to restart this activity! 2653 if (!next.hasBeenLaunched) { 2654 next.hasBeenLaunched = true; 2655 } else { 2656 if (SHOW_APP_STARTING_PREVIEW) { 2657 next.showStartingWindow(null /* prev */, false /* newTask */, 2658 false /* taskSwich */); 2659 } 2660 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next); 2661 } 2662 if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next); 2663 mStackSupervisor.startSpecificActivityLocked(next, true, true); 2664 } 2665 2666 if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); 2667 return true; 2668 } 2669
resumeTopActivityInnerLocked方法代码非常多,目前只需要关注调用了ActivityStackSupervisor的startSpecificActivityLocked方法
16.ActivityStackSupervisor.startSpecificActivityLocked
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java)
1552 void startSpecificActivityLocked(ActivityRecord r, 1553 boolean andResume, boolean checkConfig) { 1554 // Is this activity's application already running? 1555 ProcessRecord app = mService.getProcessRecordLocked(r.processName, 1556 r.info.applicationInfo.uid, true); 1557 1558 r.getStack().setLaunchTime(r); 1559 1560 if (app != null && app.thread != null) { 1561 try { 1562 if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 1563 || !"android".equals(r.info.packageName)) { 1564 // Don't add this if it is a platform component that is marked 1565 // to run in multiple processes, because this is actually 1566 // part of the framework so doesn't make sense to track as a 1567 // separate apk in the process. 1568 app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, 1569 mService.mProcessStats); 1570 } 1571 realStartActivityLocked(r, app, andResume, checkConfig); 1572 return; 1573 } catch (RemoteException e) { 1574 Slog.w(TAG, "Exception when starting activity " 1575 + r.intent.getComponent().flattenToShortString(), e); 1576 } 1577 1578 // If a dead object exception was thrown -- fall through to 1579 // restart the application. 1580 } 1581 1582 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, 1583 "activity", r.intent.getComponent(), false, false, true); 1584 }
在1555行获取即将要启动的Activity的所在的应用程序进程。
在1560行判断要启动的Activity的所在应用程序进程已经运行的话,就会调用1571行的realStartActivityLocked方法,需要注意的是,这个方法的第二个参数是代表要启动的Activity的所在的应用程序进程的ProcessRecord。
17.ActivityStackSupervisor.realStartActivityLocked
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java)
1325 final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, 1326 boolean andResume, boolean checkConfig) throws RemoteException { 1327 ................................................................... 1462 1463 final MergedConfiguration mergedConfiguration = new MergedConfiguration( 1464 mService.getGlobalConfiguration(), r.getMergedOverrideConfiguration()); 1465 r.setLastReportedConfiguration(mergedConfiguration); 1466 1467 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, 1468 System.identityHashCode(r), r.info, 1469 // TODO: Have this take the merged configuration instead of separate global and 1470 // override configs. 1471 mergedConfiguration.getGlobalConfiguration(), 1472 mergedConfiguration.getOverrideConfiguration(), r.compat, 1473 r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, 1474 r.persistentState, results, newIntents, !andResume, 1475 mService.isNextTransitionForward(), profilerInfo); 1476
................................................................. 1548 1549 return true; 1550 }
这里的 app.thread指的是IApplicationThread,它的实现是ActivityThread的内部类ApplicationThread,其中ApplicationThread继承了IApplicationThread.Stub。app指的是传入的要启动的Activity的所在的应用程序进程,因此,注释1处的代码指的就是要在目标应用程序进程启动Activity。当前代码逻辑运行在AMS所在的进程(SyetemServer进程),通过ApplicationThread来与应用程序进程进行Binder通信,换句话说,ApplicationThread是AMS所在进程(SyetemServer进程)和应用程序进程的通信桥梁。
三、 ActivityThread启动Activity的过程
18.ActivityThread.scheduleLaunchActivity
代码路径:/frameworks/base/core/java/android/app/ActivityThread.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ActivityThread.java)
748 // we use token to identify this activity without having to send the 749 // activity itself back to the activity manager. (matters more with ipc) 750 @Override 751 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, 752 ActivityInfo info, Configuration curConfig, Configuration overrideConfig, 753 CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, 754 int procState, Bundle state, PersistableBundle persistentState, 755 List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, 756 boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) { 757 758 updateProcessState(procState, false); 759 760 ActivityClientRecord r = new ActivityClientRecord(); 761 762 r.token = token; 763 r.ident = ident; 764 r.intent = intent; 765 r.referrer = referrer; 766 r.voiceInteractor = voiceInteractor; 767 r.activityInfo = info; 768 r.compatInfo = compatInfo; 769 r.state = state; 770 r.persistentState = persistentState; 771 772 r.pendingResults = pendingResults; 773 r.pendingIntents = pendingNewIntents; 774 775 r.startsNotResumed = notResumed; 776 r.isForward = isForward; 777 778 r.profilerInfo = profilerInfo; 779 780 r.overrideConfig = overrideConfig; 781 updatePendingConfiguration(curConfig); 782 783 sendMessage(H.LAUNCH_ACTIVITY, r); 784 } 785
scheduleLaunchActivity方法会将启动Activity的参数封装成ActivityClientRecord ,sendMessage方法向H类发送类型为LAUNCH_ACTIVITY的消息,并将ActivityClientRecord 传递过去,sendMessage方法有多个重载方法,最终调用的sendMessage方法如下所示
19.ActivityThread.sendMessage
代码路径:/frameworks/base/core/java/android/app/ActivityThread.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ActivityThread.java)2632 private void sendMessage(int what, Object obj) { 2633 sendMessage(what, obj, 0, 0, false); 2634 } ..................................... 2643 2644 private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { 2645 if (DEBUG_MESSAGES) Slog.v( 2646 TAG, "SCHEDULE " + what + " " + mH.codeToString(what) 2647 + ": " + arg1 + " / " + obj); 2648 Message msg = Message.obtain(); 2649 msg.what = what; 2650 msg.obj = obj; 2651 msg.arg1 = arg1; 2652 msg.arg2 = arg2; 2653 if (async) { 2654 msg.setAsynchronous(true); 2655 } 2656 mH.sendMessage(msg); 2657 }
2656行mH指的是H,它是ActivityThread的内部类并继承Handler,是应用程序进程中主线程的消息管理类
20.H.handleMessage
代码路径:/frameworks/base/core/java/android/app/ActivityThread.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ActivityThread.java)
1462 private class H extends Handler { 1463 public static final int LAUNCH_ACTIVITY = 100; 1464 public static final int PAUSE_ACTIVITY = 101; ........................................... 1521 1522 String codeToString(int code) { 1523 if (DEBUG_MESSAGES) { 1524 switch (code) { 1525 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY"; 1526 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY"; ........................................ 1580 } 1581 } 1582 return Integer.toString(code); 1583 } 1584 public void handleMessage(Message msg) { 1585 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); 1586 switch (msg.what) { 1587 case LAUNCH_ACTIVITY: { 1588 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); 1589 final ActivityClientRecord r = (ActivityClientRecord) msg.obj; 1590 1591 r.packageInfo = getPackageInfoNoCheck( 1592 r.activityInfo.applicationInfo, r.compatInfo); 1593 handleLaunchActivity(r, null, "LAUNCH_ACTIVITY"); 1594 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1595 } break; .................................... 1602 case PAUSE_ACTIVITY: { 1603 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); 1604 SomeArgs args = (SomeArgs) msg.obj; 1605 handlePauseActivity((IBinder) args.arg1, false, 1606 (args.argi1 & USER_LEAVING) != 0, args.argi2, 1607 (args.argi1 & DONT_REPORT) != 0, args.argi3); 1608 maybeSnapshot(); 1609 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1610 } break; ................................... 1859 } 1860 Object obj = msg.obj; 1861 if (obj instanceof SomeArgs) { 1862 ((SomeArgs) obj).recycle(); 1863 } 1864 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what)); 1865 } 1866
.......................................... 1892 }
查看H的handleMessage方法中对LAUNCH_ACTIVITY的处理,在1589行将传过来的msg的成员变量obj转换为ActivityClientRecord。
在1591行通过getPackageInfoNoCheck方法获得LoadedApk类型的对象并赋值给ActivityClientRecord 的成员变量packageInfo 。应用程序进程要启动Activity时需要将该Activity所属的APK加载进来,而LoadedApk就是用来描述已加载的APK文件。
在1593行调用handleLaunchActivity方法
21.ActivityThread.handleLaunchActivity
代码路径:/frameworks/base/core/java/android/app/ActivityThread.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ActivityThread.java)2872 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { .............................................. 2891 2892 Activity a = performLaunchActivity(r, customIntent); 2893 2894 if (a != null) { 2895 r.createdConfig = new Configuration(mConfiguration); 2896 reportSizeConfigurations(r); 2897 Bundle oldState = r.state; 2898 handleResumeActivity(r.token, false, r.isForward, 2899 !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason); 2900 ................................................... 2920 } else { 2921 // If there was an error, for any reason, tell the activity manager to stop us. 2922 try { 2923 ActivityManager.getService() 2924 .finishActivity(r.token, Activity.RESULT_CANCELED, null, 2925 Activity.DONT_FINISH_TASK_WITH_ACTIVITY); 2926 } catch (RemoteException ex) { 2927 throw ex.rethrowFromSystemServer(); 2928 } 2929 } 2930 }
在2892行的performLaunchActivity方法用来启动Activity 。
在2898行用来将Activity 的状态置为Resume。如果该Activity为null则会通知AMS停止启动Activity。
22.ActivityThread.performLaunchActivity
代码路径:/frameworks/base/core/java/android/app/ActivityThread.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ActivityThread.java)
2683 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { 2684 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")"); 2685 2686 ActivityInfo aInfo = r.activityInfo; 2687 if (r.packageInfo == null) { 2688 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, 2689 Context.CONTEXT_INCLUDE_CODE); 2690 } 2691 2692 ComponentName component = r.intent.getComponent(); ............................. 2703 2704 ContextImpl appContext = createBaseContextForActivity(r); 2705 Activity activity = null; 2706 try { 2707 java.lang.ClassLoader cl = appContext.getClassLoader(); 2708 activity = mInstrumentation.newActivity( 2709 cl, component.getClassName(), r.intent); 2710 StrictMode.incrementExpectedActivityCount(activity.getClass()); 2711 r.intent.setExtrasClassLoader(cl); 2712 r.intent.prepareToEnterProcess(); 2713 if (r.state != null) { 2714 r.state.setClassLoader(cl); 2715 } 2716 } catch (Exception e) { 2717 if (!mInstrumentation.onException(activity, e)) { 2718 throw new RuntimeException( 2719 "Unable to instantiate activity " + component 2720 + ": " + e.toString(), e); 2721 } 2722 } 2723 2724 try { 2725 Application app = r.packageInfo.makeApplication(false, mInstrumentation); 2726 ............................... 2750 activity.attach(appContext, this, getInstrumentation(), r.token, 2751 r.ident, app, r.intent, r.activityInfo, title, r.parent, 2752 r.embeddedID, r.lastNonConfigurationInstances, config, 2753 r.referrer, r.voiceInteractor, window, r.configCallback); 2754 2755 if (customIntent != null) { 2756 activity.mIntent = customIntent; 2757 } 2758 r.lastNonConfigurationInstances = null; 2759 checkAndBlockForNetworkAccess(); 2760 activity.mStartedActivity = false; 2761 int theme = r.activityInfo.getThemeResource(); 2762 if (theme != 0) { 2763 activity.setTheme(theme); 2764 } 2765 2766 activity.mCalled = false; 2767 if (r.isPersistable()) { 2768 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); 2769 } else { 2770 mInstrumentation.callActivityOnCreate(activity, r.state); 2771 } 2772 if (!activity.mCalled) { 2773 throw new SuperNotCalledException( 2774 "Activity " + r.intent.getComponent().toShortString() + 2775 " did not call through to super.onCreate()"); 2776 } 2777 r.activity = activity; 2778 r.stopped = true; 2779 if (!r.activity.mFinished) { 2780 activity.performStart(); 2781 r.stopped = false; 2782 } 2783 if (!r.activity.mFinished) { 2784 if (r.isPersistable()) { 2785 if (r.state != null || r.persistentState != null) { 2786 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, 2787 r.persistentState); 2788 } 2789 } else if (r.state != null) { 2790 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state); 2791 } 2792 } 2793 if (!r.activity.mFinished) { 2794 activity.mCalled = false; 2795 if (r.isPersistable()) { 2796 mInstrumentation.callActivityOnPostCreate(activity, r.state, 2797 r.persistentState); 2798 } else { 2799 mInstrumentation.callActivityOnPostCreate(activity, r.state); 2800 } 2801 if (!activity.mCalled) { 2802 throw new SuperNotCalledException( 2803 "Activity " + r.intent.getComponent().toShortString() + 2804 " did not call through to super.onPostCreate()"); 2805 } 2806 } 2807 } 2808 r.paused = true; 2809 2810 mActivities.put(r.token, r); 2811 2812 } catch (SuperNotCalledException e) { 2813 throw e; 2814 2815 } catch (Exception e) { 2816 if (!mInstrumentation.onException(activity, e)) { 2817 throw new RuntimeException( 2818 "Unable to start activity " + component 2819 + ": " + e.toString(), e); 2820 } 2821 } 2822 2823 return activity; 2824 }
在2686行用来获取ActivityInfo,ActivityInfo用于存储代码和AndroidManifes设置的Activity和receiver节点信息,比如Activity的theme和launchMode。
在2688行获取APK文件的描述类LoadedApk。
在2692行获取要启动的Activity的ComponentName类,ComponentName类中保存了该Activity的包名和类名。
在2704行用来创建要启动Activity的上下文环境。
在2708行根据ComponentName中存储的Activity类名,用类加载器来创建该Activity的实例。
在2725行用来创建Application,makeApplication方法内部会调用Application的onCreate方法。
在2750行调用Activity的attach方法初始化Activity,attach方法中会创建Window对象(PhoneWindow)并与Activity自身进行关联。
在2796行会调用Instrumentation的callActivityOnCreate方法来启动Activity
23.Instrumentation.callActivityOnCreate
代码路径:/frameworks/base/core/java/android/app/Instrumentation.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/Instrumentation.java)
1224 public void callActivityOnCreate(Activity activity, Bundle icicle, 1225 PersistableBundle persistentState) { 1226 prePerformCreate(activity); 1227 activity.performCreate(icicle, persistentState); 1228 postPerformCreate(activity); 1229 }
在1227行调用了Activity的performCreate方法
24.Instrumentation.performCreate
代码路径:/frameworks/base/core/java/android/app/Instrumentation.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/Instrumentation.java)
6980 final void performCreate(Bundle icicle, PersistableBundle persistentState) { 6981 restoreHasCurrentPermissionRequest(icicle); 6982 onCreate(icicle, persistentState); 6983 mActivityTransitionState.readState(icicle); 6984 performCreateCommon(); 6985 }
performCreate方法中会调用Activity的onCreate方法,讲到这里,根Activity就启动了,即应用程序就启动了
四、根Activity启动过程中涉及的进程
在应用程序进程没有创建的情况下,根Activity启动过程中会涉及到4个进程,分别是Zygote进程、Launcher进程、AMS所在进程(SyetemServer进程)、应用程序进程。它们之间的关系如下图所示。
首先Launcher进程向AMS请求创建根Activity,AMS会判断根Activity所需的应用程序进程是否存在并启动,如果不存在就会请求Zygote进程创建应用程序进程。应用程序进程准备就绪后会通知AMS,AMS会请求应用程序进程创建根Activity。关于上图中四个步骤的进程间通信方式,其中步骤2和步骤3相关的进程采用的是Socket通信,步骤1和步骤4相关的进程采用的Binder通信。
上图可能并不是很直观,为了更好的理解,下面给出这四个进程调用的时序图。