本篇所涉及知识点:
- Android 从开机到第一个Activity onCreate的过程粗略分析
- Activity_A进入Activity_B生命周期的回调详细过程(Activity_A的onPause-->Activity_B的onCreate,onStart,onResume-->Activity_A的onStop,期间会看到Activity的onSaveInstanceState(),OnRestoreInstanceState(),OnRestart()方法的回调源码)
需要了解的几点概念和知识点:
-
Instrumentation是执行application instrumentation代码的基类,这个类在任何application code之前实例化,让你可以监听所有的system与application之间的交互,一个应用程序中只有一个Instrumentation对象,每个Activity内部都有一个该对象的引用Instrumentation可以帮助管理Activity生命周期的回调,通过追踪源码会发现,Instrumentation的callActivityOnPause最终会去调用activity的performPause(),
- ActivityResult是Instrumentation的一个内部类,是Activity返回的一个结果,包含了resultCode和resultData
- ActivityThread类: 该类为应用程序的主线程类,所有的APK程序都有且仅有一个ActivityThread类 ,程序的入口为该类中的static main()函数
- IApplicationThread是一个接口
-
ApplicationThreadNative是一个抽象类,实现了IApplicationThread接口,并继承Binder,具有Binder通信能力,public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
- ApplicationThread 继承了ApplicationThreadNative,是ActivityThread 的一个内部类
- H也是ActivityThread的一个内部类,继承Handler,处理Activty,Service等生命周期的回调消息
- ActivityStackSupervisor 类是用来辅助管理ActivityStack的,里面有mHomeStack,mFocusedStack 和 mLastFocusedStack,它们的类型都是ActivityStack ,ActivityStackSupervisor 中主要是对它们的调度算法的一些操作
-
盗用一张图,出自http://blog.****.net/caowenbin/article/details/6036726
-
关于上图的说明:
- Binder是一种架构,这种架构提供了服务端接口、Binder驱动、客户端接口三个模块,用于完成进程间通信(IPC)
- IActivityManager是一个接口
- ActivityManagerNative 继承了 Binder 和实现了IActivityManager接口 ,具有Binder通信能力
- ActivityManagerService 继承了 ActivityManagerNative,是最核心的服务之一,负责管理Activity
- ActivityManagerProxy是ActivityManagerNative的一个内部类,也实现了IActivityManager接口
- 在开发过程中,程序员能接触到的也就是ActivityManager,系统不希望用户直接访问ActivityManagerService,而是经过ActivityManager类去访问,比如说通过activityManager.getRecentTasks得到最近使用的程序,在前面的博客《一个叫GUN的有趣的APP》使用过这个方法
- 但是ActivityManagerService和ActivityManager运行在不同的进程中,它们到底是如何通信的?这就是Proxy代理模式:为其他对象提供一种代理以控制这个对象的访问。
- activityManager.getRecentTasks动作真正的执行者是ActivityManagerService.getRecentTasks,关于这点,下面会有具体的代码分析
说明:以下源码基于android-22(5.1)分析。
Android 从开机到第一个Activity onCreate的过程大致分析
- 开机后,Linux启动,然后Linux再启动第一个进程init
- 在init中,又会启动Zygote
- Zygote则会启动SystemServer
-
SystemServer又会开启Application FrameWork中的AMS(Activity Manager Service),PMS(package Manager Service),WMS(WindowManager Service)等,这导致的结果就是Android 开机比较慢
-
在被SystemServer启动的AMS中,有一个叫startHomeActivityLocked的函数,它创建一个CATEGORY_HOME类型的Intent,而PackageManagerService会查询Category类型为HOME的Activity,因为只有系统自带的Launcher应用程序注册了HOME类型的Activity(如果有多个Launcher的话,系统会弹出一个选择框让用户选择进入哪一个Launcher)
- 然后又会执行mMainStack.startActivityLocked启动Launcher的Activity
- 接下来就是调用它的onCreate
这样总算从开机一步一步走到了Activity的第一个执行的生命周期。
说明1:android的launcher应用程序,即桌面应用程序(注意,Android开机启动后的桌面也是一个APP,只不过这个APP有点特殊,开发难度有点大而已,Android原生系统的launcher的包名叫"com.android.launcher",小米launcher的包名叫"com.miui.home",这是以前写《一个叫GUN的有趣的APP》时发现的),这个launcher负责把安装在手机上的APP以快捷图标的形式展示出来。
说明2:因为以上涉及到Linux方面知识,因为完全不懂,只弄懂了大致流程,所以不敢保证上面的进程步骤严谨正确(以后待研究)。
Activity_A进入Activity_B生命周期的回调详细过程
执行代码:
- Intent intent = new Intent(Activity_A.this, Activity_B.class);
- startActivity(intent);
它们的生命周期执行过程:
对于这个生命周期的执行过程,应该都很熟了,但是有一点疑问:为什么执行了Activity_A的onPause之后就直接去执行Activity_B的onCreate,onStart,onResume,最后才掉过头回去执行Activity_A的onStop?
进入源码分析(因为所涉及到的代码逻辑太多太多,所以以下分析主要基于Activity生命周期回调执行的主线)。
Activity.class
- public void startActivity(Intent intent) {
- this.startActivity(intent, null);
- }
-
- public void startActivity(Intent intent, @Nullable Bundle options) {
- if (options != null) {
- startActivityForResult(intent, -1, options);
- } else {
- // Note we want to go through this call for compatibility with
- // applications that may have overridden the method.
- startActivityForResult(intent, -1);
- }
- }
-
- public void startActivityForResult(Intent intent, int requestCode,
- @Nullable Bundle options) {
- if (mParent == null) {
- //这是关键的一句,启动新的Activity
- Instrumentation.ActivityResult ar = mInstrumentation
- .execStartActivity(this,
- mMainThread.getApplicationThread(), mToken, this,
- intent, requestCode, options);
- if (ar != null) {
- mMainThread.sendActivityResult(mToken, mEmbeddedID,
- requestCode, ar.getResultCode(), ar.getResultData());
- }
- if (requestCode >= 0) {
- // If this start is requesting a result, we can avoid making
- // the activity visible until the result is received. Setting
- // this code during onCreate(Bundle savedInstanceState) or
- // onResume() will keep the
- // activity hidden during this time, to avoid flickering.
- // This can only be done when a result is requested because
- // that guarantees we will get information back when the
- // activity is finished, no matter what happens to it.
- mStartedActivity = true;
- }
-
- final View decor = mWindow != null ? mWindow.peekDecorView() : null;
- if (decor != null) {
- decor.cancelPendingInputEvents();
- }
- // TODO Consider clearing/flushing other event sources and events
- // for child windows.
- } else {
- if (options != null) {
- mParent.startActivityFromChild(this, intent, requestCode,
- options);
- } else {
- // Note we want to go through this method for compatibility with
- // existing applications that may have overridden it.
- mParent.startActivityFromChild(this, intent, requestCode);
- }
- }
- if (options != null && !isTopOfTask()) {
- mActivityTransitionState.startExitOutTransition(this, options);
- }
- }
非常非常关键的mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
这个mInstrumentation就是上面提到的Instrumentation,引用《Android内核剖析》对它的描述:一个应用程序中只有一个Instrumentation对象,每个Activity内部都有一个该对象的引用。Instrumentation可以理解为应用进程的管家, ActivityThread要创建或者暂停某 个 Activity时,是 通 过 这 个“ 管家” 进行的,设置这个管家的好处是可以统计所有的“ 开销”,开销的信息保存在“ 管家” 那里。其实正如其名称所示,Instrumentation就是为了 “测量”、 “统计”,因为管家掌握了所有的“ 开销”,自然也就具有了统计的功能。当然,Instrumentation类 和 ActivityThread的分工是有本质区别的,后者就像是这个家里的主人,负责创建这个“家庭”,并负责和外界打交道,比如 接 收AMS的通知等。
Instrumentation可以帮助管理Activity生命周期的回调。
Instrumentation.class
- public ActivityResult execStartActivity(
- Context who, IBinder contextThread, IBinder token, Activity target,
- Intent intent, int requestCode, Bundle options) {
- IApplicationThread whoThread = (IApplicationThread) contextThread;
- if (mActivityMonitors != null) {
- synchronized (mSync) {
- final int N = mActivityMonitors.size();
- for (int i=0; i<N; i++) {
- final ActivityMonitor am = mActivityMonitors.get(i);
- if (am.match(who, null, intent)) {
- am.mHits++;
- if (am.isBlocking()) {
- return requestCode >= 0 ? am.getResult() : null;
- }
- break;
- }
- }
- }
- }
- try {
- intent.migrateExtraStreamToClipData();
- intent.prepareToLeaveProcess();
- //关键,Proxy代理模式,真正的动作执行者是ActivityManagerService.startActivity
- int result = ActivityManagerNative.getDefault()
- .startActivity(whoThread, who.getBasePackageName(), intent,
- intent.resolveTypeIfNeeded(who.getContentResolver()),
- token, target != null ? target.mEmbeddedID : null,
- requestCode, 0, null, options);
- checkStartActivityResult(result, intent);
- } catch (RemoteException e) {
- }
- return null;
- }
大致介绍一下Proxy代理模式,看看这个ActivityManagerNative.getDefault()到底是什么?
ActivityManagerNative.class
- /**
- * Retrieve the system's default/global activity manager.
- */
- static public IActivityManager getDefault() {
- return gDefault.get();
- }
-
- private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
- protected IActivityManager create() {
- IBinder b = ServiceManager.getService("activity");
- if (false) {
- Log.v("ActivityManager", "default service binder = " + b);
- }
- IActivityManager am = asInterface(b);
- if (false) {
- Log.v("ActivityManager", "default service = " + am);
- }
- return am;
- }
- };
说明:
IBinder是用来通信的,getDefault()返回的是一个IActivityManager类型的ActivityManagerProxy对象,代理的是ActivityManagerNative类的子类ActivityManagerService,代理成功之后,便可以通过这个代理对象使用IBinder和系统不希望用户直接访问的ActivityManagerService进行通信,并执行ActivityManagerService中具体定义的动作了。
再次以activityManager.getRecentTasks为例再进行说明:
ActivityManager.class
- @Deprecated
- public List<RecentTaskInfo> getRecentTasks(int maxNum, int flags)
- throws SecurityException {
- try {
- return ActivityManagerNative.getDefault().getRecentTasks(maxNum,
- flags, UserHandle.myUserId());
- } catch (RemoteException e) {
- // System dead, we will be dead too soon!
- return null;
- }
- }
这里也是通过ActivityManagerNative.getDefault()代理,ActivityManager并没有执行其具体的动作,真正动作的执行在通过ActivityManagerNative.getDefault()代理的ActivityManagerService里面。
代理模式大致理解了,继续分析:
- ActivityManagerNative.getDefault()
- .startActivity(whoThread, who.getBasePackageName(), intent,
- intent.resolveTypeIfNeeded(who.getContentResolver()),
- token, target != null ? target.mEmbeddedID : null,
- requestCode, 0, null, options);
里面的参数whoThread就是前面的MainThread.getApplicationThread,mMainThread的类型是ActivityThread,它代表的是应用程序的主线程,这里通过 mMainThread.getApplicationThread获得它里面的ApplicationThread成员变量,具有Binder通信能力。
按照上面的分析,现在可以知道ActivityManagerNative.getDefault().startActivity真正的动作执行是在ActivityManagerService.startActivity里面,跟踪源码:
ActivityManagerService.class
- @Override
- public final int startActivity(IApplicationThread caller, String callingPackage,
- Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, ProfilerInfo profilerInfo, Bundle options) {
- return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
- resultWho, requestCode, startFlags, profilerInfo, options,
- UserHandle.getCallingUserId());
- }
-
- @Override
- public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
- Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
- int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
- enforceNotIsolatedCaller("startActivity");
- userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
- false, ALLOW_FULL_ONLY, "startActivity", null);
- // TODO: Switch to user app stacks here.
- return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
- resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
- profilerInfo, null, null, options, userId, null, null);
- }
ActivityStackSupervisor.class
- final int startActivityMayWait(IApplicationThread caller, int callingUid,
- String callingPackage, Intent intent, String resolvedType,
- IVoiceInteractionSession voiceSession,
- IVoiceInteractor voiceInteractor, IBinder resultTo,
- String resultWho, int requestCode, int startFlags,
- ProfilerInfo profilerInfo, WaitResult outResult,
- Configuration config, Bundle options, int userId,
- IActivityContainer iContainer, TaskRecord inTask) {
- // Refuse possible leaked file descriptors
- if (intent != null && intent.hasFileDescriptors()) {
- throw new IllegalArgumentException(
- "File descriptors passed in Intent");
- }
- // ...
-
- if (aInfo != null
- && (aInfo.applicationInfo.flags & ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
- // ...
- }
-
- int res = startActivityLocked(caller, intent, resolvedType, aInfo,
- voiceSession, voiceInteractor, resultTo, resultWho,
- requestCode, callingPid, callingUid, callingPackage,
- realCallingPid, realCallingUid, startFlags, options,
- componentSpecified, null, container, inTask);
-
- // ...
-
- return res;
- }
ActivityStackSupervisor 类是用来辅助管理ActivityStack的,在ActivityStackSupervisor中可以看到
ActivityStackSupervisor.class
- /** The stack containing the launcher app. Assumed to always be attached to
- * Display.DEFAULT_DISPLAY. */
- private ActivityStack mHomeStack;
-
- /** The stack currently receiving input or launching the next activity. */
- private ActivityStack mFocusedStack;
-
- /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
- * been resumed. If stacks are changing position this will hold the old stack until the new
- * stack becomes resumed after which it will be set to mFocusedStack. */
- private ActivityStack mLastFocusedStack;
里面有mHomeStack,mFocusedStack 和 mLastFocusedStack,它们的类型都是ActivityStack 。从Google注释中可以理解,mHomeStack保存launcher app的Activity,mFocusedStack保存当前接受输入事件和正启动的下一个Activity。ActivityStackSupervisor 中主要是对它们的调度算法的一些操作。
上面startActivityMayWait返回的结果是通过startActivityLocked得到的res,继续追踪startActivityLocked:
ActivityStackSupervisor.class
- final int startActivityLocked(IApplicationThread caller,
- Intent intent, String resolvedType, ActivityInfo aInfo,
- IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
- IBinder resultTo, String resultWho, int requestCode,
- int callingPid, int callingUid, String callingPackage,
- int realCallingPid, int realCallingUid, int startFlags, Bundle options,
- boolean componentSpecified, ActivityRecord[] outActivity, ActivityContainer container,
- TaskRecord inTask) {
- int err = ActivityManager.START_SUCCESS;
- ProcessRecord callerApp = null;
- if (caller != null) {
- //...
- }
- //...
- if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
- //...
- }
-
- if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
- // We couldn't find a class that can handle the given Intent.
- // That's the end of that!
- err = ActivityManager.START_INTENT_NOT_RESOLVED;
- }
-
- if (err == ActivityManager.START_SUCCESS && aInfo == null) {
- // We couldn't find the specific class specified in the Intent.
- // Also the end of the line.
- err = ActivityManager.START_CLASS_NOT_FOUND;
- }
- //...
- err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
- startFlags, true, options, inTask);
- //...
- return err;
- }
主要是检查目标APP或者Activity的一些信息,包括是否存在,是否拥有权限等,最后又会调用startActivityUncheckedLocked,此时目标Activity经过了通过了检查。
startActivityUncheckedLocked中又调用了targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options),这里跟上面的ActivityStackSupervisor.startActivityLocked方法名相同。
ActivityStack.class
- final void startActivityLocked(ActivityRecord r, boolean newTask,
- boolean doResume, boolean keepCurTransition, Bundle options) {
- TaskRecord rTask = r.task;
- final int taskId = rTask.taskId;
- // mLaunchTaskBehind tasks get placed at the back of the task stack.
- if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
- // Last activity in task had been removed or ActivityManagerService is reusing task.
- // Insert or replace.
- // Might not even be in.
- //如果是新任务,插入栈顶
- insertTaskAtTop(rTask);
- mWindowManager.moveTaskToTop(taskId);
- }
- TaskRecord task = null;
- if (!newTask) {
- // If starting in an existing task, find where that is...
- //如果不是是新任务
- boolean startIt = true;
- //遍历mHistory
- for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
- task = mTaskHistory.get(taskNdx);
- if (task.getTopActivity() == null) {
- // All activities in task are finishing.
- continue;
- }
- if (task == r.task) {
- // Here it is! Now, if this is not yet visible to the
- // user, then just add it without starting; it will
- // get started when the user navigates back to it.
- if (!startIt) {
- if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
- + task, new RuntimeException("here").fillInStackTrace());
- task.addActivityToTop(r);
- r.putInHistory();
- mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
- r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
- (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
- r.userId, r.info.configChanges, task.voiceSession != null,
- r.mLaunchTaskBehind);
- if (VALIDATE_TOKENS) {
- validateAppTokensLocked();
- }
- ActivityOptions.abort(options);
- return;
- }
- break;
- } else if (task.numFullscreen > 0) {
- startIt = false;
- }
- }
- }
-
- // Place a new activity at top of stack, so it is next to interact
- // with the user.
-
- // If we are not placing the new activity frontmost, we do not want
- // to deliver the onUserLeaving callback to the actual frontmost
- // activity
- if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
- //...
- }
-
- //...
- if (!isHomeStack() || numActivities() > 0) {
- //...
- } else {
- //...
- }
- if (VALIDATE_TOKENS) {
- validateAppTokensLocked();
- }
-
- if (doResume) {
- mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
- }
- }
在ActivityStackSupervisor.startActivityUncheckedLocked和ActivityStack.startActivityLocked主要是找到或创建合适的Task,根据FLAG_ACTIVITY_XX(启动模式)进行不同的Task操作,这里调度task的算法很复杂。 上面执行完成之后,调用mStackSupervisor.resumeTopActivitiesLocked(this, r, options);ActivityStack
ActivityStackSupervisor.class
- boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
- Bundle targetOptions) {
- if (targetStack == null) {
- targetStack = getFocusedStack();
- }
- // Do targetStack first.
- boolean result = false;
- if (isFrontStack(targetStack)) {
- result = targetStack.resumeTopActivityLocked(target, targetOptions);
- }
- for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
- final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
- for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = stacks.get(stackNdx);
- if (stack == targetStack) {
- // Already started above.
- continue;
- }
- if (isFrontStack(stack)) {
- stack.resumeTopActivityLocked(null);
- }
- }
- }
- return result;
- }
ActivityStack.class
- final boolean resumeTopActivityLocked(ActivityRecord prev) {
- return resumeTopActivityLocked(prev, null);
- }
-
- final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
- if (mStackSupervisor.inResumeTopActivity) {
- // Don't even start recursing.
- return false;
- }
-
- boolean result = false;
- try {
- // Protect against recursion.
- mStackSupervisor.inResumeTopActivity = true;
- if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
- mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
- mService.updateSleepIfNeededLocked();
- }
- result = resumeTopActivityInnerLocked(prev, options);
- } finally {
- mStackSupervisor.inResumeTopActivity = false;
- }
- return result;
- }
ActivityStack.class
resumeTopActivityInnerLocked方法里面代码太多
- final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
- //...
-
- // Find the first activity that is not finishing.
- //找到第一个没有finish的activity,这个Activity就是Activity_A
- final ActivityRecord next = topRunningActivityLocked(null);
-
- // Remember how we'll process this pause/resume situation, and ensure
- // that the state is reset however we wind up proceeding.
- final boolean userLeaving = mStackSupervisor.mUserLeaving;
- mStackSupervisor.mUserLeaving = false;
-
- final TaskRecord prevTask = prev != null ? prev.task : null;
- //如果是开机启动,则next==null,所以就是启动Launcher了
- if (next == null) {
- // There are no more activities! Let's just start up the
- // Launcher...
- ActivityOptions.abort(options);
- if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
- if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
- // Only resume home if on home display
- final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
- HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
- return isOnHomeDisplay() &&
- mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "noMoreActivities");
- }
-
-
- //...
- // We need to start pausing the current activity so the top one
- // can be resumed...
- //去 pause当前处于resumed状态的Activity,也就是Activity_A
- boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
- boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
- if (mResumedActivity != null) {
- if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
- pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
- }
- //...
- if (prev != null && prev != next) {}
-
- //...
-
- return true;
- }
这里先分析Launcher的启动函数 resumeHomeStackTask
ActivityStackSupervisor.class
- boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev, String reason) {
- if (!mService.mBooting && !mService.mBooted) {
- // Not ready yet!
- return false;
- }
-
- if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
- mWindowManager.showRecentApps();
- return false;
- }
- moveHomeStackTaskToTop(homeStackTaskType, reason);
- if (prev != null) {
- prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
- }
-
- ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
- // if (r != null && (r.isHomeActivity() || r.isRecentsActivity())) {
- if (r != null && r.isHomeActivity()) {
- mService.setFocusedActivityLocked(r, reason);
- return resumeTopActivitiesLocked(mHomeStack, prev, null);
- }
- //启动Launcher
- return mService.startHomeActivityLocked(mCurrentUser, reason);
- }
mService.startHomeActivityLocked(mCurrentUser, reason)启动Launcher
ActivityManagerService.class
- boolean startHomeActivityLocked(int userId, String reason) {
- if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
- && mTopAction == null) {
- // We are running in factory test mode, but unable to find
- // the factory test app, so just sit around displaying the
- // error message and don't try to start anything.
- return false;
- }
- Intent intent = getHomeIntent();
- ActivityInfo aInfo =
- resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
- if (aInfo != null) {
- intent.setComponent(new ComponentName(
- aInfo.applicationInfo.packageName, aInfo.name));
- // Don't do this if the home app is currently being
- // instrumented.
- aInfo = new ActivityInfo(aInfo);
- aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
- ProcessRecord app = getProcessRecordLocked(aInfo.processName,
- aInfo.applicationInfo.uid, true);
- if (app == null || app.instrumentationClass == null) {
- intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
- mStackSupervisor.startHomeActivity(intent, aInfo, reason);
- }
- }
-
- return true;
- }
ActivityStackSupervisor.class
- void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
- moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE, reason);
- startActivityLocked(null, intent, null, aInfo, null, null, null, null, 0, 0, 0, null,
- 0, 0, 0, null, false, null, null, null);
- }
里面也是调用了startActivityLocked,如果想定义自己的Launcher的话,貌似就可以在这里修改代码了。
再去追踪startPausingLocked
ActivityStack.class
- final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
- boolean dontWait) {
- if (mPausingActivity != null) {
- Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity);
- completePauseLocked(false);
- }
- //prev包含了Activity_A,所以prev.app != null && prev.app.thread != null
- ActivityRecord prev = mResumedActivity;
- if (prev == null) {
- if (!resuming) {
- Slog.wtf(TAG, "Trying to pause when nothing is resumed");
- mStackSupervisor.resumeTopActivitiesLocked();
- }
- return false;
- }
- //...
- if (prev.app != null && prev.app.thread != null) {
- if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);
- try {
- EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
- prev.userId, System.identityHashCode(prev),
- prev.shortComponentName);
- mService.updateUsageStats(prev, false);
- //这句是关键,通过Binder调用ActivityThread中的方法,AmS 会通过 IPC 调用到 ActivityThread 的schedulePauseActivity
- prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
- userLeaving, prev.configChangeFlags, dontWait);
- } catch (Exception e) {
- // Ignore exception, if process died other code will cleanup.
- Slog.w(TAG, "Exception thrown during pause", e);
- mPausingActivity = null;
- mLastPausedActivity = null;
- mLastNoHistoryActivity = null;
- }
- } else {
- mPausingActivity = null;
- mLastPausedActivity = null;
- mLastNoHistoryActivity = null;
- }
-
- //...
- return false;
- }
疑问:为什么prev.app.thread.schedulePauseActivity能调用到ApplicationThread中的schedulePauseActivity方法?
----Binder机制,具体怎么实现的我也没弄明白。
ActivityThread.class
ApplicationThread是ActivityThread的一个内部类,有木有感觉里面的方法是那么熟悉?
- private class ApplicationThread extends ApplicationThreadNative {
-
- //...
- public final void schedulePauseActivity(IBinder token, boolean finished,
- boolean userLeaving, int configChanges, boolean dontReport) {
- sendMessage(
- finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
- token,
- (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
- configChanges);
- }
-
- public final void scheduleStopActivity(IBinder token, boolean showWindow,
- int configChanges) {
- sendMessage(
- showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
- token, 0, configChanges);
- }
-
- public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
- sendMessage(
- showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
- token);
- }
-
- public final void scheduleSleeping(IBinder token, boolean sleeping) {
- sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
- }
-
- public final void scheduleResumeActivity(IBinder token, int processState,
- boolean isForward, Bundle resumeArgs) {
- updateProcessState(processState, false);
- sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
- }
-
- public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
- ResultData res = new ResultData();
- res.token = token;
- res.results = results;
- sendMessage(H.SEND_RESULT, res);
- }
-
- // we use token to identify this activity without having to send the
- // activity itself back to the activity manager. (matters more with ipc)
- public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
- ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
- String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
- PersistableBundle persistentState, List<ResultInfo> pendingResults,
- List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,
- ProfilerInfo profilerInfo) {
-
- updateProcessState(procState, false);
-
- ActivityClientRecord r = new ActivityClientRecord();
-
- r.token = token;
- r.ident = ident;
- r.intent = intent;
- r.referrer = referrer;
- r.voiceInteractor = voiceInteractor;
- r.activityInfo = info;
- r.compatInfo = compatInfo;
- r.state = state;
- r.persistentState = persistentState;
-
- r.pendingResults = pendingResults;
- r.pendingIntents = pendingNewIntents;
-
- r.startsNotResumed = notResumed;
- r.isForward = isForward;
-
- r.profilerInfo = profilerInfo;
-
- updatePendingConfiguration(curConfig);
-
- sendMessage(H.LAUNCH_ACTIVITY, r);
- }
-
- public final void scheduleRelaunchActivity(IBinder token,
- List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
- int configChanges, boolean notResumed, Configuration config) {
- requestRelaunchActivity(token, pendingResults, pendingNewIntents,
- configChanges, notResumed, config, true);
- }
-
- public final void scheduleNewIntent(List<ReferrerIntent> intents, IBinder token) {
- NewIntentData data = new NewIntentData();
- data.intents = intents;
- data.token = token;
-
- sendMessage(H.NEW_INTENT, data);
- }
-
- public final void scheduleDestroyActivity(IBinder token, boolean finishing,
- int configChanges) {
- sendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
- configChanges);
- }
-
- public final void scheduleReceiver(Intent intent, ActivityInfo info,
- CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
- boolean sync, int sendingUser, int processState) {
- updateProcessState(processState, false);
- ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
- sync, false, mAppThread.asBinder(), sendingUser);
- r.info = info;
- r.compatInfo = compatInfo;
- sendMessage(H.RECEIVER, r);
- }
-
- //...
- public final void scheduleCreateService(IBinder token,
- ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
- updateProcessState(processState, false);
- CreateServiceData s = new CreateServiceData();
- s.token = token;
- s.info = info;
- s.compatInfo = compatInfo;
-
- sendMessage(H.CREATE_SERVICE, s);
- }
-
- public final void scheduleBindService(IBinder token, Intent intent,
- boolean rebind, int processState) {
- updateProcessState(processState, false);
- BindServiceData s = new BindServiceData();
- s.token = token;
- s.intent = intent;
- s.rebind = rebind;
-
- if (DEBUG_SERVICE)
- Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
- + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
- sendMessage(H.BIND_SERVICE, s);
- }
-
- //...
- }
schedulePauseActivity里面有个H.PAUSE_ACTIVITY_FINISHING。 前面说过,H也是ActivityThread的一个内部类,继承Handler,用来处理Activty,Service等生命周期的回调消息。关于Handler Loopr的通信原理,可以参考一下以前写过一篇博文《从Android源码角度对Handler,MessageQueue,Looper之间消息传递工作原理的理解》。 ActivityThread.class
- private class H extends Handler {
-
- public void handleMessage(Message msg) {
- if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
- switch (msg.what) {
- case LAUNCH_ACTIVITY: {
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
- final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
-
- r.packageInfo = getPackageInfoNoCheck(
- r.activityInfo.applicationInfo, r.compatInfo);
- handleLaunchActivity(r, null);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- } break;
- case RELAUNCH_ACTIVITY: {
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
- ActivityClientRecord r = (ActivityClientRecord)msg.obj;
- handleRelaunchActivity(r);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- } break;
- case PAUSE_ACTIVITY:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
- handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
- (msg.arg1&2) != 0);
- maybeSnapshot();
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case PAUSE_ACTIVITY_FINISHING:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
- handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2,
- (msg.arg1&1) != 0);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case STOP_ACTIVITY_SHOW:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
- handleStopActivity((IBinder)msg.obj, true, msg.arg2);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- case STOP_ACTIVITY_HIDE:
- Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
- handleStopActivity((IBinder)msg.obj, false, msg.arg2);
- Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
- break;
- //...
- }
ActivityThread.class
- private void handlePauseActivity(IBinder token, boolean finished,
- boolean userLeaving, int configChanges, boolean dontReport) {
- ActivityClientRecord r = mActivities.get(token);
- if (r != null) {
- //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
- if (userLeaving) {
- performUserLeavingActivity(r);
- }
-
- r.activity.mConfigChangeFlags |= configChanges;
- performPauseActivity(token, finished, r.isPreHoneycomb());
-
- // Make sure any pending writes are now committed.
- if (r.isPreHoneycomb()) {
- QueuedWork.waitToFinish();
- }
-
- // Tell the activity manager we have paused.
- if (!dontReport) {
- try {
- ActivityManagerNative.getDefault().activityPaused(token);
- } catch (RemoteException ex) {
- }
- }
- mSomeActivitiesChanged = true;
- }
- }
ActivityThread.class
- final Bundle performPauseActivity(IBinder token, boolean finished,
- boolean saveState) {
- ActivityClientRecord r = mActivities.get(token);
- return r != null ? performPauseActivity(r, finished, saveState) : null;
- }
-
-
- final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
- boolean saveState) {
- if (r.paused) {
- //...
- }
- if (finished) {
- //...
- }
- try {
- // Next have the activity save its current state and managed dialogs...
- //通知Activity_A调用onSaveInstanceState保存状态
- if (!r.activity.mFinished && saveState) {
- callCallActivityOnSaveInstanceState(r);
- }
- // Now we are idle.
- //通知Activity_A调用OnPause方法
- r.activity.mCalled = false;
- mInstrumentation.callActivityOnPause(r.activity);
- EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
- r.activity.getComponentName().getClassName());
- if (!r.activity.mCalled) {
- throw new SuperNotCalledException(
- "Activity " + r.intent.getComponent().toShortString() +
- " did not call through to super.onPause()");
- }
-
- } catch (SuperNotCalledException e) {
- throw e;
-
- } catch (Exception e) {
- //...
- }
- r.paused = true;
- return !r.activity.mFinished && saveState ? r.state : null;
- }
在这里终于明白了,在启动目标Activity前,如果当前正在运行任何Activity,那么必须首先暂停。
追踪mInstrumentation.callActivityOnPause(r.activity)
Instrumentation.class
- public void callActivityOnPause(Activity activity) {
- activity.performPause();
- }
Activity.class
- final void performPause() {
- mDoReportFullyDrawn = false;
- mFragments.dispatchPause();
- mCalled = false;
- onPause();
- mResumed = false;
- if (!mCalled && getApplicationInfo().targetSdkVersion
- >= android.os.Build.VERSION_CODES.GINGERBREAD) {
- throw new SuperNotCalledException(
- "Activity " + mComponent.toShortString() +
- " did not call through to super.onPause()");
- }
- mResumed = false;
- }
终于看到了Activity的onPause方法,至此,Activity_A已经执行onPause方法,Activity_B未执行其生命周期的任何方法。
在下一篇中将继续去追踪Activity_B生命周期回调源码。