赞
踩
本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net
在 Android 系统中,Activity 和 Service 是应用程序的核心组件,它们以松藕合的方式组合在一起构成了一个完整的应用程序,这得益于应用程序框架层提供了一套完整的机制来协助应用程序启动这些 Activity 和 Service,以及提供 Binder 机制帮助它们相互间进行通信。
在 Android 系统中,有两种操作会引发 Activity 的启动,一种用户点击应用程序图标时,Launcher 会为我们启动应用程序的主 Activity;应用程序的默认 Activity 启动起来后,它又可以在内部通过调用 startActvity 接口启动新的 Activity,依此类推,每一个 Activity 都可以在内部启动新的 Activity。通过这种连锁反应,按需启动 Activity,从而完成应用程序的功能。
这里,我们通过一个具体的例子来说明如何启动 Android 应用程序的 Activity。Activity 的启动方式有两种,一种是显式的,一种是隐式的,隐式启动可以使得 Activity 之间的藕合性更加松散,因此,这里只关注隐式启动 Activity 的方法。
① 点击桌面 App 图标,Launcher 进程采用 Binder IPC 向 system_server 进程发起 startActivity 请求;
② system_server 进程接收到请求后,向 zygote 进程发送创建进程的请求;
③ Zygote 进程 fork 出新的子进程,即 App 进程;
④ App 进程,通过 Binder IPC 向 sytem_server 进程发起 attachApplication 请求;
⑤ system_server 进程在收到请求后,进行一系列准备工作后,再通过 binder IPC 向 App 进程发送 scheduleLaunchActivity 请求;
⑥ App 进程的 Binder (ApplicationThread)在收到请求后,通过 handler 向主线程发送 LAUNCH_ACTIVITY 消息;
⑦ 主线程在收到 Message 后,通过发射机制创建目标 Activity,并回调 Activity.onCreate() 等方法。
⑧ 到此,App 便正式启动,开始进入 Activity 生命周期,执行完 onCreate/onStart/onResume 方法,UI 渲染结束后便可以看到 App 的主界面。
在 Android 系统中,应用程序是由 Launcher 启动起来的,其实,Launcher 本身也是一个应用程序,其它的应用程序安装后,就会 Launcher 的界面上出现一个相应的图标,点击这个图标时,Launcher 就会对应的应用程序启动起来。
Launcher 的源代码工程在 packages/apps/Launcher2 目录下,负责启动其它应用程序的源代码实现在 src/com/android/launcher2/Launcher.java 文件中:
/** * Default launcher application. */ public final class Launcher extends Activity implements View.OnClickListener, OnLongClickListener, LauncherModel.Callbacks, AllAppsView.Watcher { ...... /** * Launches the intent referred by the clicked shortcut. * * @param v The view representing the clicked shortcut. */ public void onClick(View v) { Object tag = v.getTag(); if (tag instanceof ShortcutInfo) { // Open shortcut final Intent intent = ((ShortcutInfo) tag).intent; int[] pos = new int[2]; v.getLocationOnScreen(pos); intent.setSourceBounds(new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight())); startActivitySafely(intent, tag); } else if (tag instanceof FolderInfo) { ...... } else if (v == mHandleView) { ...... } } void startActivitySafely(Intent intent, Object tag) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { startActivity(intent); } catch (ActivityNotFoundException e) { ...... } catch (SecurityException e) { ...... } } ...... }
它的默认 Activity 是 MainActivity,这里是 AndroidManifest.xml 文件中配置的:
<activity android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
因此,这里的 intent 包含的信息为:action = “android.intent.action.Main”,category=“android.intent.category.LAUNCHER”, cmp=“shy.luo.activity/.MainActivity”,表示它要启动的 Activity 为 shy.luo.activity.MainActivity。Intent.FLAG_ACTIVITY_NEW_TASK 表示要在一个新的 Task 中启动这个 Activity,注意,Task 是 Android 系统中的概念,它不同于进程 Process 的概念。简单地说,一个 Task 是一系列 Activity 的集合,这个集合是以堆栈的形式来组织的,遵循后进先出的原则。事实上,Task 是一个非常复杂的概念,有兴趣的读者可以到官网查看相关的资料。这里,我们只要知道,这个 MainActivity 要在一个新的 Task 中启动就可以了。
在 Step 1 中,我们看到,Launcher 继承于 Activity 类,而 Activity 类实现了 startActivity 函数,因此,这里就调用了 Activity.startActivity 函数,它实现在 frameworks/base/core/java/android/app/Activity.java 文件中:
public class Activity extends ContextThemeWrapper implements LayoutInflater.Factory, Window.Callback, KeyEvent.Callback, OnCreateContextMenuListener, ComponentCallbacks { ...... @Override public void startActivity(Intent intent) { startActivityForResult(intent, -1); } ...... }
这个函数实现很简单,它调用 startActivityForResult 来进一步处理,第二个参数传入 - 1 表示不需要这个 Actvity 结束后的返回结果。
这个函数也是实现在 frameworks/base/core/java/android/app/Activity.java 文件中:
public class Activity extends ContextThemeWrapper implements LayoutInflater.Factory, Window.Callback, KeyEvent.Callback, OnCreateContextMenuListener, ComponentCallbacks { ...... public void startActivityForResult(Intent intent, int requestCode) { if (mParent == null) { Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode); ...... } else { ...... } ...... }
这里的 mInstrumentation 是 Activity 类的成员变量,它的类型是 Intrumentation,定义在 frameworks/base/core/java/android/app/Instrumentation.java 文件中,它用来监控应用程序和系统的交互。
这里的 mMainThread 也是 Activity 类的成员变量,它的类型是 ActivityThread,它代表的是应用程序的主线程。这里通过 mMainThread.getApplicationThread 获得它里面的 ApplicationThread 成员变量,它是一个 Binder 对象,后面我们会看到,ActivityManagerService 会使用它来和 ActivityThread 来进行进程间通信。这里我们需注意的是,这里的 mMainThread 代表的是 Launcher 应用程序运行的进程。
这里的 mToken 也是 Activity 类的成员变量,它是一个 Binder 对象的远程接口。
这个函数定义在 frameworks/base/core/java/android/app/Instrumentation.java 文件中:
public class Instrumentation { ...... public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode) { IApplicationThread whoThread = (IApplicationThread) contextThread; if (mActivityMonitors != null) { ...... } try { int result = ActivityManagerNative.getDefault() .startActivity(whoThread, intent, intent.resolveTypeIfNeeded(who.getContentResolver()), null, 0, token, target != null ? target.mEmbeddedID : null, requestCode, false, false); ...... } catch (RemoteException e) { } return null; } ...... }
这里的 ActivityManagerNative.getDefault 返回 ActivityManagerService 的远程接口,即 ActivityManagerProxy 接口。
这里的 intent.resolveTypeIfNeeded 返回这个 intent 的 MIME 类型,在这个例子中,没有 AndroidManifest.xml 设置 MainActivity 的 MIME 类型,因此,这里返回 null。
这里的 target 不为 null,但是 target.mEmbddedID 为 null,我们不用关注。
这个函数定义在 frameworks/base/core/java/android/app/ActivityManagerNative.java 文件中:
class ActivityManagerProxy implements IActivityManager { ...... public int startActivity(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); intent.writeToParcel(data, 0); data.writeString(resolvedType); data.writeTypedArray(grantedUriPermissions, 0); data.writeInt(grantedMode); data.writeStrongBinder(resultTo); data.writeString(resultWho); data.writeInt(requestCode); data.writeInt(onlyIfNeeded ? 1 : 0); data.writeInt(debug ? 1 : 0); mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); reply.readException(); int result = reply.readInt(); reply.recycle(); data.recycle(); return result; } ...... }
这里的参数比较多,我们先整理一下。从上面的调用可以知道,这里的参数 resolvedType、grantedUriPermissions 和 resultWho 均为 null;参数 caller 为 ApplicationThread 类型的 Binder 实体;参数 resultTo 为一个 Binder 实体的远程接口,我们先不关注它;参数 grantedMode 为 0,我们也先不关注它;参数 requestCode 为 - 1;参数 onlyIfNeeded 和 debug 均空 false。
上一步 Step 5 通过 Binder 驱动程序就进入到 ActivityManagerService 的 startActivity 函数来了,它定义在 frameworks/base/services/java/com/android/server/am/ActivityManagerService.java 文件中:
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... public final int startActivity(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug) { return mMainStack.startActivityMayWait(caller, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug, null, null); } ...... }
这里只是简单地将操作转发给成员变量 mMainStack 的 startActivityMayWait 函数,这里的 mMainStack 的类型为 ActivityStack。
这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityStack.java 文件中:
public class ActivityStack { ...... final int startActivityMayWait(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, IBinder resultTo, String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug, WaitResult outResult, Configuration config) { ...... boolean componentSpecified = intent.getComponent() != null; // Don't modify the client's object! intent = new Intent(intent); // Collect information about the target of the Intent. ActivityInfo aInfo; try { ResolveInfo rInfo = AppGlobals.getPackageManager().resolveIntent( intent, resolvedType, PackageManager.MATCH_DEFAULT_ONLY | ActivityManagerService.STOCK_PM_FLAGS); aInfo = rInfo != null ? rInfo.activityInfo : null; } catch (RemoteException e) { ...... } if (aInfo != null) { // Store the found target back into the intent, because now that // we have it we never want to do this again. For example, if the // user navigates back to this point in the history, we should // always restart the exact same activity. intent.setComponent(new ComponentName( aInfo.applicationInfo.packageName, aInfo.name)); ...... } synchronized (mService) { int callingPid; int callingUid; if (caller == null) { ...... } else { callingPid = callingUid = -1; } mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0; ...... if (mMainStack && aInfo != null && (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { ...... } int res = startActivityLocked(caller, intent, resolvedType, grantedUriPermissions, grantedMode, aInfo, resultTo, resultWho, requestCode, callingPid, callingUid, onlyIfNeeded, componentSpecified); if (mConfigWillChange && mMainStack) { ...... } ...... if (outResult != null) { ...... } return res; } } ...... }
注意,从 Step 6 传下来的参数 outResult 和 config 均为 null,此外,表达式 (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0 为 false,因此,这里忽略了无关代码。
下面语句对参数 intent 的内容进行解析,得到 MainActivity 的相关信息,保存在 aInfo 变量中:
ActivityInfo aInfo;
try {
ResolveInfo rInfo =
AppGlobals.getPackageManager().resolveIntent(
intent, resolvedType,
PackageManager.MATCH_DEFAULT_ONLY
| ActivityManagerService.STOCK_PM_FLAGS);
aInfo = rInfo != null ? rInfo.activityInfo : null;
} catch (RemoteException e) {
......
}
解析之后,得到的 aInfo.applicationInfo.packageName 的值为 “shy.luo.activity”,aInfo.name 的值为 “shy.luo.activity.MainActivity”,这是在这个实例的配置文件 AndroidManifest.xml 里面配置的。
此外,函数开始的地方调用 intent.getComponent() 函数的返回值不为 null,因此,这里的 componentSpecified 变量为 true。
这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityStack.java 文件中:
public class ActivityStack { ...... final int startActivityLocked(IApplicationThread caller, Intent intent, String resolvedType, Uri[] grantedUriPermissions, int grantedMode, ActivityInfo aInfo, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, boolean onlyIfNeeded, boolean componentSpecified) { int err = START_SUCCESS; ProcessRecord callerApp = null; if (caller != null) { callerApp = mService.getRecordForAppLocked(caller); if (callerApp != null) { callingPid = callerApp.pid; callingUid = callerApp.info.uid; } else { ...... } } ...... ActivityRecord sourceRecord = null; ActivityRecord resultRecord = null; if (resultTo != null) { int index = indexOfTokenLocked(resultTo); ...... if (index >= 0) { sourceRecord = (ActivityRecord)mHistory.get(index); if (requestCode >= 0 && !sourceRecord.finishing) { ...... } } } int launchFlags = intent.getFlags(); if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) { ...... } if (err == START_SUCCESS && intent.getComponent() == null) { ...... } if (err == START_SUCCESS && aInfo == null) { ...... } if (err != START_SUCCESS) { ...... } ...... ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid, intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, requestCode, componentSpecified); ...... return startActivityUncheckedLocked(r, sourceRecord, grantedUriPermissions, grantedMode, onlyIfNeeded, true); } ...... }
从传进来的参数 caller 得到调用者的进程信息,并保存在 callerApp 变量中,这里就是 Launcher 应用程序的进程信息了。
前面说过,参数 resultTo 是 Launcher 这个 Activity 里面的一个 Binder 对象,通过它可以获得 Launcher 这个 Activity 的相关信息,保存在 sourceRecord 变量中。
再接下来,创建即将要启动的 Activity 的相关信息,并保存在 r 变量中:
ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid,
intent, resolvedType, aInfo, mService.mConfiguration,
resultRecord, resultWho, requestCode, componentSpecified);
接着调用 startActivityUncheckedLocked 函数进行下一步操作。
这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityStack.java 文件中:
public class ActivityStack { ...... final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord, Uri[] grantedUriPermissions, int grantedMode, boolean onlyIfNeeded, boolean doResume) { final Intent intent = r.intent; final int callingUid = r.launchedFromUid; int launchFlags = intent.getFlags(); // We'll invoke onUserLeaving before onPause only if the launching // activity did not explicitly state that this is an automated launch. mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0; ...... ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; // If the onlyIfNeeded flag is set, then we can do this if the activity // being launched is the same as the one making the call... or, as // a special case, if we do not know the caller then we count the // current top activity as the caller. if (onlyIfNeeded) { ...... } if (sourceRecord == null) { ...... } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { ...... } else if (r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) { ...... } if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { ...... } boolean addingToTask = false; if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { // If bring to front is requested, and no result is requested, and // we can find a task that was started with this same // component, then instead of launching bring that one to the front. if (r.resultTo == null) { // See if there is a task to bring to the front. If this is // a SINGLE_INSTANCE activity, there can be one and only one // instance of it in the history, and it is always in its own // unique task, so we do a special search. ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE ? findTaskLocked(intent, r.info) : findActivityLocked(intent, r.info); if (taskTop != null) { ...... } } } ...... if (r.packageName != null) { // If the activity being launched is the same as the one currently // at the top, then we need to check if it should only be launched // once. ActivityRecord top = topRunningNonDelayedActivityLocked(notTop); if (top != null && r.resultTo == null) { if (top.realActivity.equals(r.realActivity)) { ...... } } } else { ...... } boolean newTask = false; // Should this be considered a new task? if (r.resultTo == null && !addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { // todo: should do better management of integers. mService.mCurTask++; if (mService.mCurTask <= 0) { mService.mCurTask = 1; } r.task = new TaskRecord(mService.mCurTask, r.info, intent, (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); ...... newTask = true; if (mMainStack) { mService.addRecentTaskLocked(r.task); } } else if (sourceRecord != null) { ...... } else { ...... } ...... startActivityLocked(r, newTask, doResume); return START_SUCCESS; } ...... }
函数首先获得 intent 的标志值,保存在 launchFlags 变量中。
这个 intent 的标志值的位 Intent.FLAG_ACTIVITY_NO_USER_ACTION 没有置位,因此 ,成员变量 mUserLeaving 的值为 true。
这个 intent 的标志值的位 Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP 也没有置位,因此,变量 notTop 的值为 null。
由于在这个例子的 AndroidManifest.xml 文件中,MainActivity 没有配置 launchMode 属值,因此,这里的 r.launchMode 为默认值 0,表示以标准(Standard,或者称为 ActivityInfo.LAUNCH_MULTIPLE)的方式来启动这个 Activity。Activity 的启动方式有四种,其余三种分别是 ActivityInfo.LAUNCH_SINGLE_INSTANCE、ActivityInfo.LAUNCH_SINGLE_TASK 和 ActivityInfo.LAUNCH_SINGLE_TOP,具体可以参考官方网站
传进来的参数 r.resultTo 为 null,表示 Launcher 不需要等这个即将要启动的 MainActivity 的执行结果。
由于这个 intent 的标志值的位 Intent.FLAG_ACTIVITY_NEW_TASK 被置位,而且 Intent.FLAG_ACTIVITY_MULTIPLE_TASK 没有置位,因此,下面的 if 语句会被执行:
if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0) || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) { // If bring to front is requested, and no result is requested, and // we can find a task that was started with this same // component, then instead of launching bring that one to the front. if (r.resultTo == null) { // See if there is a task to bring to the front. If this is // a SINGLE_INSTANCE activity, there can be one and only one // instance of it in the history, and it is always in its own // unique task, so we do a special search. ActivityRecord taskTop = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE ? findTaskLocked(intent, r.info) : findActivityLocked(intent, r.info); if (taskTop != null) { ...... } } }
这段代码的逻辑是查看一下,当前有没有 Task 可以用来执行这个 Activity。由于 r.launchMode 的值不为 ActivityInfo.LAUNCH_SINGLE_INSTANCE,因此,它通过 findTaskLocked 函数来查找存不存这样的 Task,这里返回的结果是 null,即 taskTop 为 null,因此,需要创建一个新的 Task 来启动这个 Activity。
接着往下看:
if (r.packageName != null) {
// If the activity being launched is the same as the one currently
// at the top, then we need to check if it should only be launched
// once.
ActivityRecord top = topRunningNonDelayedActivityLocked(notTop);
if (top != null && r.resultTo == null) {
if (top.realActivity.equals(r.realActivity)) {
......
}
}
}
这段代码的逻辑是看一下,当前在堆栈顶端的 Activity 是否就是即将要启动的 Activity,有些情况下,如果即将要启动的 Activity 就在堆栈的顶端,那么,就不会重新启动这个 Activity 的别一个实例了,具体可以参考官方网站。现在处理堆栈顶端的 Activity 是 Launcher,与我们即将要启动的 MainActivity 不是同一个 Activity,因此,这里不用进一步处理上述介绍的情况。
执行到这里,我们知道,要在一个新的 Task 里面来启动这个 Activity 了,于是新创建一个 Task:
if (r.resultTo == null && !addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { // todo: should do better management of integers. mService.mCurTask++; if (mService.mCurTask <= 0) { mService.mCurTask = 1; } r.task = new TaskRecord(mService.mCurTask, r.info, intent, (r.info.flags&ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH) != 0); ...... newTask = true; if (mMainStack) { mService.addRecentTaskLocked(r.task); } }
新建的 Task 保存在 r.task 域中,同时,添加到 mService 中去,这里的 mService 就是 ActivityManagerService 了。
最后就进入 startActivityLocked(r, newTask, doResume) 进一步处理了。这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityStack.java 文件中:
public class ActivityStack { ...... private final void startActivityLocked(ActivityRecord r, boolean newTask, boolean doResume) { final int NH = mHistory.size(); int addPos = -1; if (!newTask) { ...... } // Place a new activity at top of stack, so it is next to interact // with the user. if (addPos < 0) { addPos = NH; } // If we are not placing the new activity frontmost, we do not want // to deliver the onUserLeaving callback to the actual frontmost // activity if (addPos < NH) { ...... } // Slot the activity into the history stack and proceed mHistory.add(addPos, r); r.inHistory = true; r.frontOfTask = newTask; r.task.numActivities++; if (NH > 0) { // We want to show the starting preview window if we are // switching to a new task, or the next activity's process is // not currently running. ...... } else { // If this is the first activity, don't do any fancy animations, // because there is nothing for it to animate on top of. ...... } ...... if (doResume) { resumeTopActivityLocked(null); } } ...... }
这里的 NH 表示当前系统中历史任务的个数,这里肯定是大于 0,因为 Launcher 已经跑起来了。当 NH>0 时,并且现在要切换新任务时,要做一些任务切的界面操作,这段代码我们就不看了,这里不会影响到下面启 Activity 的过程,有兴趣的读取可以自己研究一下。
这里传进来的参数 doResume 为 true,于是调用 resumeTopActivityLocked 进一步操作。
这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityStack.java 文件中:
public class ActivityStack { ...... /** * Ensure that the top activity in the stack is resumed. * * @param prev The previously resumed activity, for when in the process * of pausing; can be null to call from elsewhere. * * @return Returns true if something is being resumed, or false if * nothing happened. */ final boolean resumeTopActivityLocked(ActivityRecord prev) { // Find the first activity that is not finishing. 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 = mUserLeaving; mUserLeaving = false; if (next == null) { ...... } next.delayedResume = false; // If the top activity is the resumed one, nothing to do. if (mResumedActivity == next && next.state == ActivityState.RESUMED) { ...... } // If we are sleeping, and there is no resumed activity, and the top // activity is paused, well that is the state we want. if ((mService.mSleeping || mService.mShuttingDown) && mLastPausedActivity == next && next.state == ActivityState.PAUSED) { ...... } ...... // If we are currently pausing an activity, then don't do anything // until that is done. if (mPausingActivity != null) { ...... } ...... // We need to start pausing the current activity so the top one // can be resumed... if (mResumedActivity != null) { ...... startPausingLocked(userLeaving, false); return true; } ...... } ...... }
函数先通过调用 topRunningActivityLocked 函数获得堆栈顶端的 Activity,这里就是 MainActivity 了,这是在上面的 Step 9 设置好的,保存在 next 变量中。
接下来把 mUserLeaving 的保存在本地变量 userLeaving 中,然后重新设置为 false,在上面的 Step 9 中,mUserLeaving 的值为 true,因此,这里的 userLeaving 为 true。
这里的 mResumedActivity 为 Launcher,因为 Launcher 是当前正被执行的 Activity。
当我们处理休眠状态时,mLastPausedActivity 保存堆栈顶端的 Activity,因为当前不是休眠状态,所以 mLastPausedActivity 为 null。
有了这些信息之后,下面的语句就容易理解了:
// If the top activity is the resumed one, nothing to do.
if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
......
}
// If we are sleeping, and there is no resumed activity, and the top
// activity is paused, well that is the state we want.
if ((mService.mSleeping || mService.mShuttingDown)
&& mLastPausedActivity == next && next.state == ActivityState.PAUSED) {
......
}
它首先看要启动的 Activity 是否就是当前处理 Resumed 状态的 Activity,如果是的话,那就什么都不用做,直接返回就可以了;否则再看一下系统当前是否休眠状态,如果是的话,再看看要启动的 Activity 是否就是当前处于堆栈顶端的 Activity,如果是的话,也是什么都不用做。
上面两个条件都不满足,因此,在继续往下执行之前,首先要把当处于 Resumed 状态的 Activity 推入 Paused 状态,然后才可以启动新的 Activity。但是在将当前这个 Resumed 状态的 Activity 推入 Paused 状态之前,首先要看一下当前是否有 Activity 正在进入 Pausing 状态,如果有的话,当前这个 Resumed 状态的 Activity 就要稍后才能进入 Paused 状态了,这样就保证了所有需要进入 Paused 状态的 Activity 串行处理。
这里没有处于 Pausing 状态的 Activity,即 mPausingActivity 为 null,而且 mResumedActivity 也不为 null,于是就调用 startPausingLocked 函数把 Launcher 推入 Paused 状态去了。
这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityStack.java 文件中:
public class ActivityStack { ...... private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) { if (mPausingActivity != null) { ...... } ActivityRecord prev = mResumedActivity; if (prev == null) { ...... } ...... mResumedActivity = null; mPausingActivity = prev; mLastPausedActivity = prev; prev.state = ActivityState.PAUSING; ...... if (prev.app != null && prev.app.thread != null) { ...... try { ...... prev.app.thread.schedulePauseActivity(prev, prev.finishing, userLeaving, prev.configChangeFlags); ...... } catch (Exception e) { ...... } } else { ...... } ...... } ...... }
函数首先把 mResumedActivity 保存在本地变量 prev 中。在上一步 Step 10 中,说到 mResumedActivity 就是 Launcher,因此,这里把 Launcher 进程中的 ApplicationThread 对象取出来,通过它来通知 Launcher 这个 Activity 它要进入 Paused 状态了。当然,这里的 prev.app.thread 是一个 ApplicationThread 对象的远程接口,通过调用这个远程接口的 schedulePauseActivity 来通知 Launcher 进入 Paused 状态。
参数 prev.finishing 表示 prev 所代表的 Activity 是否正在等待结束的 Activity 列表中,由于 Laucher 这个 Activity 还没结束,所以这里为 false;参数 prev.configChangeFlags 表示哪些 config 发生了变化,这里我们不关心它的值。
这个函数定义在 frameworks/base/core/java/android/app/ApplicationThreadNative.java 文件中:
class ApplicationThreadProxy implements IApplicationThread { ...... public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); data.writeStrongBinder(token); data.writeInt(finished ? 1 : 0); data.writeInt(userLeaving ? 1 :0); data.writeInt(configChanges); mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } ...... }
这个函数通过 Binder 进程间通信机制进入到 ApplicationThread.schedulePauseActivity 函数中。
这个函数定义在 frameworks/base/core/java/android/app/ActivityThread.java 文件中,它是 ActivityThread 的内部类:
public final class ActivityThread { ...... private final class ApplicationThread extends ApplicationThreadNative { ...... public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges) { queueOrSendMessage( finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY, token, (userLeaving ? 1 : 0), configChanges); } ...... } ...... }
这里调用的函数 queueOrSendMessage 是 ActivityThread 类的成员函数。
上面说到,这里的 finished 值为 false,因此,queueOrSendMessage 的第一个参数值为 H.PAUSE_ACTIVITY,表示要暂停 token 所代表的 Activity,即 Launcher。
这个函数定义在 frameworks/base/core/java/android/app/ActivityThread.java 文件中:
public final class ActivityThread { ...... private final void queueOrSendMessage(int what, Object obj, int arg1) { queueOrSendMessage(what, obj, arg1, 0); } private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) { synchronized (this) { ...... Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; mH.sendMessage(msg); } } ...... }
这里首先将相关信息组装成一个 msg,然后通过 mH 成员变量发送出去,mH 的类型是 H,继承于 Handler 类,是 ActivityThread 的内部类,因此,这个消息最后由 H.handleMessage 来处理。
这个函数定义在 frameworks/base/core/java/android/app/ActivityThread.java 文件中:
public final class ActivityThread { ...... private final class H extends Handler { ...... public void handleMessage(Message msg) { ...... switch (msg.what) { ...... case PAUSE_ACTIVITY: handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2); maybeSnapshot(); break; ...... } ...... } ...... }
这里调用 ActivityThread.handlePauseActivity 进一步操作,msg.obj 是一个 ActivityRecord 对象的引用,它代表的是 Launcher 这个 Activity。
这个函数定义在 frameworks/base/core/java/android/app/ActivityThread.java 文件中:
public final class ActivityThread { ...... private final void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges) { 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; Bundle state = performPauseActivity(token, finished, true); // Make sure any pending writes are now committed. QueuedWork.waitToFinish(); // Tell the activity manager we have paused. try { ActivityManagerNative.getDefault().activityPaused(token, state); } catch (RemoteException ex) { } } } ...... }
函数首先将 Binder 引用 token 转换成 ActivityRecord 的远程接口 ActivityClientRecord,然后做了三个事情:1. 如果 userLeaving 为 true,则通过调用 performUserLeavingActivity 函数来调用 Activity.onUserLeaveHint 通知 Activity,用户要离开它了;2. 调用 performPauseActivity 函数来调用 Activity.onPause 函数,我们知道,在 Activity 的生命周期中,当它要让位于其它的 Activity 时,系统就会调用它的 onPause 函数;3. 它通知 ActivityManagerService,这个 Activity 已经进入 Paused 状态了,ActivityManagerService 现在可以完成未竟的事情,即启动 MainActivity 了。
这个函数定义在 frameworks/base/core/java/android/app/ActivityManagerNative.java 文件中:
class ActivityManagerProxy implements IActivityManager { ...... public void activityPaused(IBinder token, Bundle state) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(token); data.writeBundle(state); mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); } ...... }
这里通过 Binder 进程间通信机制就进入到 ActivityManagerService.activityPaused 函数中去了。
这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityManagerService.java 文件中:
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... public final void activityPaused(IBinder token, Bundle icicle) { ...... final long origId = Binder.clearCallingIdentity(); mMainStack.activityPaused(token, icicle, false); ...... } ...... }
这里,又再次进入到 ActivityStack 类中,执行 activityPaused 函数。
这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityStack.java 文件中:
public class ActivityStack { ...... final void activityPaused(IBinder token, Bundle icicle, boolean timeout) { ...... ActivityRecord r = null; synchronized (mService) { int index = indexOfTokenLocked(token); if (index >= 0) { r = (ActivityRecord)mHistory.get(index); if (!timeout) { r.icicle = icicle; r.haveState = true; } mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); if (mPausingActivity == r) { r.state = ActivityState.PAUSED; completePauseLocked(); } else { ...... } } } } ...... }
这里通过参数 token 在 mHistory 列表中得到 ActivityRecord,从上面我们知道,这个 ActivityRecord 代表的是 Launcher 这个 Activity,而我们在 Step 11 中,把 Launcher 这个 Activity 的信息保存在 mPausingActivity 中,因此,这里 mPausingActivity 等于 r,于是,执行 completePauseLocked 操作。
这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityStack.java 文件中:
public class ActivityStack { ...... private final void completePauseLocked() { ActivityRecord prev = mPausingActivity; ...... if (prev != null) { ...... mPausingActivity = null; } if (!mService.mSleeping && !mService.mShuttingDown) { resumeTopActivityLocked(prev); } else { ...... } ...... } ...... }
函数首先把 mPausingActivity 变量清空,因为现在不需要它了,然后调用 resumeTopActivityLokced 进一步操作,它传入的参数即为代表 Launcher 这个 Activity 的 ActivityRecord。
这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityStack.java 文件中:
public class ActivityStack { ...... final boolean resumeTopActivityLocked(ActivityRecord prev) { ...... // Find the first activity that is not finishing. 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 = mUserLeaving; mUserLeaving = false; ...... next.delayedResume = false; // If the top activity is the resumed one, nothing to do. if (mResumedActivity == next && next.state == ActivityState.RESUMED) { ...... return false; } // If we are sleeping, and there is no resumed activity, and the top // activity is paused, well that is the state we want. if ((mService.mSleeping || mService.mShuttingDown) && mLastPausedActivity == next && next.state == ActivityState.PAUSED) { ...... return false; } ....... // We need to start pausing the current activity so the top one // can be resumed... if (mResumedActivity != null) { ...... return true; } ...... if (next.app != null && next.app.thread != null) { ...... } else { ...... startSpecificActivityLocked(next, true, true); } return true; } ...... }
通过上面的 Step 9,我们知道,当前在堆栈顶端的 Activity 为我们即将要启动的 MainActivity,这里通过调用 topRunningActivityLocked 将它取回来,保存在 next 变量中。之前最后一个 Resumed 状态的 Activity,即 Launcher,到了这里已经处于 Paused 状态了,因此,mResumedActivity 为 null。最后一个处于 Paused 状态的 Activity 为 Launcher,因此,这里的 mLastPausedActivity 就为 Launcher。前面我们为 MainActivity 创建了 ActivityRecord 后,它的 app 域一直保持为 null。有了这些信息后,上面这段代码就容易理解了,它最终调用 startSpecificActivityLocked 进行下一步操作。
这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityStack.java 文件中:
public class ActivityStack { ...... private final void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // Is this activity's application already running? ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid); ...... if (app != null && app.thread != null) { try { realStartActivityLocked(r, app, andResume, checkConfig); return; } catch (RemoteException e) { ...... } } mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false); } ...... }
注意,这里由于是第一次启动应用程序的 Activity,所以下面语句:
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid);
取回来的 app 为 null。在 Activity 应用程序中的 AndroidManifest.xml 配置文件中,我们没有指定 Application 标签的 process 属性,系统就会默认使用 package 的名称,这里就是 “shy.luo.activity” 了。每一个应用程序都有自己的 uid,因此,这里 uid + process 的组合就可以为每一个应用程序创建一个 ProcessRecord。当然,我们可以配置两个应用程序具有相同的 uid 和 package,或者在 AndroidManifest.xml 配置文件的 application 标签或者 activity 标签中显式指定相同的 process 属性值,这样,不同的应用程序也可以在同一个进程中启动。
函数最终执行 ActivityManagerService.startProcessLocked 函数进行下一步操作。
这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityManagerService.java 文件中:
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting) { ProcessRecord app = getProcessRecordLocked(processName, info.uid); ...... String hostingNameStr = hostingName != null ? hostingName.flattenToShortString() : null; ...... if (app == null) { app = new ProcessRecordLocked(null, info, processName); mProcessNames.put(processName, info.uid, app); } else { // If this is a new package in the process, add the package to the list app.addPackage(info.packageName); } ...... startProcessLocked(app, hostingType, hostingNameStr); return (app.pid != 0) ? app : null; } ...... }
这里再次检查是否已经有以 process + uid 命名的进程存在,在我们这个情景中,返回值 app 为 null,因此,后面会创建一个 ProcessRecord,并存保存在成员变量 mProcessNames 中,最后,调用另一个 startProcessLocked 函数进一步操作:
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) { ...... try { int uid = app.info.uid; int[] gids = null; try { gids = mContext.getPackageManager().getPackageGids( app.info.packageName); } catch (PackageManager.NameNotFoundException e) { ...... } ...... int debugFlags = 0; ...... int pid = Process.start("android.app.ActivityThread", mSimpleProcessManagement ? app.processName : null, uid, uid, gids, debugFlags, null); ...... } catch (RuntimeException e) { ...... } } ...... }
这里主要是调用 Process.start 接口来创建一个新的进程,新的进程会导入 android.app.ActivityThread 类,并且执行它的 main 函数,这就是为什么我们前面说每一个应用程序都有一个 ActivityThread 实例来对应的原因。
这个函数定义在 frameworks/base/core/java/android/app/ActivityThread.java 文件中:
public final class ActivityThread { ...... private final void attach(boolean system) { ...... mSystemThread = system; if (!system) { ...... IActivityManager mgr = ActivityManagerNative.getDefault(); try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { } } else { ...... } } ...... public static final void main(String[] args) { ....... ActivityThread thread = new ActivityThread(); thread.attach(false); ...... Looper.loop(); ....... thread.detach(); ...... } }
这个函数在进程中创建一个 ActivityThread 实例,然后调用它的 attach 函数,接着就进入消息循环了,直到最后进程退出。
函数 attach 最终调用了 ActivityManagerService 的远程接口 ActivityManagerProxy 的 attachApplication 函数,传入的参数是 mAppThread,这是一个 ApplicationThread 类型的 Binder 对象,它的作用是用来进行进程间通信的。
这个函数定义在 frameworks/base/core/java/android/app/ActivityManagerNative.java 文件中:
class ActivityManagerProxy implements IActivityManager { ...... public void attachApplication(IApplicationThread app) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(app.asBinder()); mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); } ...... }
这里通过 Binder 驱动程序,最后进入 ActivityManagerService 的 attachApplication 函数中。
这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityManagerService.java 文件中:
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } } ...... }
这里将操作转发给 attachApplicationLocked 函数。
这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityManagerService.java 文件中:
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { // Find the application record that is being attached... either via // the pid if we are running in multiple processes, or just pull the // next app record if we are emulating process with anonymous threads. ProcessRecord app; if (pid != MY_PID && pid >= 0) { synchronized (mPidsSelfLocked) { app = mPidsSelfLocked.get(pid); } } else if (mStartingProcesses.size() > 0) { ...... } else { ...... } if (app == null) { ...... return false; } ...... String processName = app.processName; try { thread.asBinder().linkToDeath(new AppDeathRecipient( app, pid, thread), 0); } catch (RemoteException e) { ...... return false; } ...... app.thread = thread; app.curAdj = app.setAdj = -100; app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; app.forcingToForeground = null; app.foregroundServices = false; app.debugging = false; ...... boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); ...... boolean badApp = false; boolean didSomething = false; // See if the top visible activity is waiting to run in this process... ActivityRecord hr = mMainStack.topRunningActivityLocked(null); if (hr != null && normalMode) { if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid && processName.equals(hr.processName)) { try { if (mMainStack.realStartActivityLocked(hr, app, true, true)) { didSomething = true; } } catch (Exception e) { ...... } } else { ...... } } ...... return true; } ...... }
在前面的 Step 23 中,已经创建了一个 ProcessRecord,这里首先通过 pid 将它取回来,放在 app 变量中,然后对 app 的其它成员进行初始化,最后调用 mMainStack.realStartActivityLocked 执行真正的 Activity 启动操作。这里要启动的 Activity 通过调用 mMainStack.topRunningActivityLocked(null) 从堆栈顶端取回来,这时候在堆栈顶端的 Activity 就是 MainActivity 了。
这个函数定义在 frameworks/base/services/java/com/android/server/am/ActivityStack.java 文件中:
public class ActivityStack { ...... final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { ...... r.app = app; ...... int idx = app.activities.indexOf(r); if (idx < 0) { app.activities.add(r); } ...... try { ...... List<ResultInfo> results = null; List<Intent> newIntents = null; if (andResume) { results = r.results; newIntents = r.newIntents; } ...... app.thread.scheduleLaunchActivity(new Intent(r.intent), r, System.identityHashCode(r), r.info, r.icicle, results, newIntents, !andResume, mService.isNextTransitionForward()); ...... } catch (RemoteException e) { ...... } ...... return true; } ...... }
这里最终通过 app.thread 进入到 ApplicationThreadProxy 的 scheduleLaunchActivity 函数中,注意,这里的第二个参数 r,是一个 ActivityRecord 类型的 Binder 对象,用来作来这个 Activity 的 token 值。
这个函数定义在 frameworks/base/core/java/android/app/ApplicationThreadNative.java 文件中:
class ApplicationThreadProxy implements IApplicationThread { ...... public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Bundle state, List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) throws RemoteException { Parcel data = Parcel.obtain(); data.writeInterfaceToken(IApplicationThread.descriptor); intent.writeToParcel(data, 0); data.writeStrongBinder(token); data.writeInt(ident); info.writeToParcel(data, 0); data.writeBundle(state); data.writeTypedList(pendingResults); data.writeTypedList(pendingNewIntents); data.writeInt(notResumed ? 1 : 0); data.writeInt(isForward ? 1 : 0); mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null, IBinder.FLAG_ONEWAY); data.recycle(); } ......
这个函数最终通过 Binder 驱动程序进入到 ApplicationThread 的 scheduleLaunchActivity 函数中。
这个函数定义在 frameworks/base/core/java/android/app/ActivityThread.java 文件中:
public final class ActivityThread { ...... private final class ApplicationThread extends ApplicationThreadNative { ...... // 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, Bundle state, List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) { ActivityClientRecord r = new ActivityClientRecord(); r.token = token; r.ident = ident; r.intent = intent; r.activityInfo = info; r.state = state; r.pendingResults = pendingResults; r.pendingIntents = pendingNewIntents; r.startsNotResumed = notResumed; r.isForward = isForward; queueOrSendMessage(H.LAUNCH_ACTIVITY, r); } ...... } ...... }
函数首先创建一个 ActivityClientRecord 实例,并且初始化它的成员变量,然后调用 ActivityThread 类的 queueOrSendMessage 函数进一步处理。
这个函数定义在 frameworks/base/core/java/android/app/ActivityThread.java 文件中:
public final class ActivityThread { ...... private final class ApplicationThread extends ApplicationThreadNative { ...... // if the thread hasn't started yet, we don't have the handler, so just // save the messages until we're ready. private final void queueOrSendMessage(int what, Object obj) { queueOrSendMessage(what, obj, 0, 0); } ...... private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) { synchronized (this) { ...... Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; mH.sendMessage(msg); } } ...... } ...... }
函数把消息内容放在 msg 中,然后通过 mH 把消息分发出去,这里的成员变量 mH 我们在前面已经见过,消息分发出去后,最后会调用 H 类的 handleMessage 函数。
这个函数定义在 frameworks/base/core/java/android/app/ActivityThread.java 文件中:
public final class ActivityThread { ...... private final class H extends Handler { ...... public void handleMessage(Message msg) { ...... switch (msg.what) { case LAUNCH_ACTIVITY: { ActivityClientRecord r = (ActivityClientRecord)msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo); handleLaunchActivity(r, null); } break; ...... } ...... } ...... }
这里最后调用 ActivityThread 类的 handleLaunchActivity 函数进一步处理。
这个函数定义在 frameworks/base/core/java/android/app/ActivityThread.java 文件中:
public final class ActivityThread { ...... private final void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { ...... Activity a = performLaunchActivity(r, customIntent); if (a != null) { r.createdConfig = new Configuration(mConfiguration); Bundle oldState = r.state; handleResumeActivity(r.token, false, r.isForward); ...... } else { ...... } } ...... }
这里首先调用 performLaunchActivity 函数来加载这个 Activity 类,即 shy.luo.activity.MainActivity,然后调用它的 onCreate 函数,最后回到 handleLaunchActivity 函数时,再调用 handleResumeActivity 函数来使这个 Activity 进入 Resumed 状态,即会调用这个 Activity 的 onResume 函数,这是遵循 Activity 的生命周期的。
这个函数定义在 frameworks/base/core/java/android/app/ActivityThread.java 文件中:
public final class ActivityThread { ...... private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, Context.CONTEXT_INCLUDE_CODE); } ComponentName component = r.intent.getComponent(); if (component == null) { component = r.intent.resolveActivity( mInitialApplication.getPackageManager()); r.intent.setComponent(component); } if (r.activityInfo.targetActivity != null) { component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity); } Activity activity = null; try { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); r.intent.setExtrasClassLoader(cl); if (r.state != null) { r.state.setClassLoader(cl); } } catch (Exception e) { ...... } try { Application app = r.packageInfo.makeApplication(false, mInstrumentation); ...... if (activity != null) { ContextImpl appContext = new ContextImpl(); appContext.init(r.packageInfo, r.token, this); appContext.setOuterContext(activity); CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mConfiguration); ...... activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstance, r.lastNonConfigurationChildInstances, config); if (customIntent != null) { activity.mIntent = customIntent; } r.lastNonConfigurationInstance = null; r.lastNonConfigurationChildInstances = null; activity.mStartedActivity = false; int theme = r.activityInfo.getThemeResource(); if (theme != 0) { activity.setTheme(theme); } activity.mCalled = false; mInstrumentation.callActivityOnCreate(activity, r.state); ...... r.activity = activity; r.stopped = true; if (!r.activity.mFinished) { activity.performStart(); r.stopped = false; } if (!r.activity.mFinished) { if (r.state != null) { mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state); } } if (!r.activity.mFinished) { activity.mCalled = false; mInstrumentation.callActivityOnPostCreate(activity, r.state); if (!activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onPostCreate()"); } } } r.paused = true; mActivities.put(r.token, r); } catch (SuperNotCalledException e) { ...... } catch (Exception e) { ...... } return activity; } ...... }
函数前面是收集要启动的 Activity 的相关信息,主要 package 和 component 信息:
ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, Context.CONTEXT_INCLUDE_CODE); } ComponentName component = r.intent.getComponent(); if (component == null) { component = r.intent.resolveActivity( mInitialApplication.getPackageManager()); r.intent.setComponent(component); } if (r.activityInfo.targetActivity != null) { component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity); }
然后通过 ClassLoader 将 shy.luo.activity.MainActivity 类加载进来:
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
r.intent.setExtrasClassLoader(cl);
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
......
}
接下来是创建 Application 对象,这是根据 AndroidManifest.xml 配置文件中的 Application 标签的信息来创建的:
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
后面的代码主要创建 Activity 的上下文信息,并通过 attach 方法将这些上下文信息设置到 MainActivity 中去:
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstance,
r.lastNonConfigurationChildInstances, config);
最后还要调用 MainActivity 的 onCreate 函数:
mInstrumentation.callActivityOnCreate(activity, r.state);
这里不是直接调用 MainActivity 的 onCreate 函数,而是通过 mInstrumentation 的 callActivityOnCreate 函数来间接调用,前面我们说过,mInstrumentation 在这里的作用是监控 Activity 与系统的交互操作,相当于是系统运行日志。
这个函数定义在 packages/experimental/Activity/src/shy/luo/activity/MainActivity.java 文件中,这是我们自定义的 app 工程文件:
public class MainActivity extends Activity implements OnClickListener {
......
@Override
public void onCreate(Bundle savedInstanceState) {
......
Log.i(LOG_TAG, "Main Activity Created.");
}
......
}
这样,MainActivity 就启动起来了,整个应用程序也启动起来了。
整个应用程序的启动过程要执行很多步骤,但是整体来看,主要分为以下五个阶段:
一. Step1 - Step 11:Launcher 通过 Binder 进程间通信机制通知 ActivityManagerService,它要启动一个 Activity;
二. Step 12 - Step 16:ActivityManagerService 通过 Binder 进程间通信机制通知 Launcher 进入 Paused 状态;
三. Step 17 - Step 24:Launcher 通过 Binder 进程间通信机制通知 ActivityManagerService,它已经准备就绪进入 Paused 状态,于是 ActivityManagerService 就创建一个新的进程,用来启动一个 ActivityThread 实例,即将要启动的 Activity 就是在这个 ActivityThread 实例中运行;
四. Step 25 - Step 27:ActivityThread 通过 Binder 进程间通信机制将一个 ApplicationThread 类型的 Binder 对象传递给 ActivityManagerService,以便以后 ActivityManagerService 能够通过这个 Binder 对象和它进行通信;
五. Step 28 - Step 35:ActivityManagerService 通过 Binder 进程间通信机制通知 ActivityThread,现在一切准备就绪,它可以真正执行 Activity 的启动操作了。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。