转载请标明原文地址:http://blog.csdn.net/yalinfendou/article/details/46909173【yalinfendou的博客】
学习Android近一年,最近几天总算把Activity启动的生命周期回调流程走通了,因为所涉及的知识点太多,赶快做了笔记,不然过几天就忘了。强烈推荐《Android内核剖析》这本书,虽然随着Android版本的不断迭代更新,代码变化了不少,仍具有很强的参考价值。
本篇所涉及知识点:
- 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.csdn.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方面知识,因为完全不懂,只弄懂了大致流程,所以不敢保证上面的进程步骤严谨正确(以后待研究)。
说明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);
按照上面的分析,现在可以知道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生命周期回调源码。
版权声明:本文为博主原创文章,未经博主允许不得转载。