写点什么

Android Framework 学习笔记(五)应用程序启动过程

发布于: 2021 年 11 月 06 日

因为 AMS 继承了 AMN,服务端真正的实现是在 AMS 中,注释 1 最终会调用 AMS 的 startActivity 方法。


ActivityManagerService#startActivity()


@Override


public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {


return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); //1


}


AMS 中 Binder 机制暂且分析到这里。


下面看从 Launcher 到 AMS 的时序图:



image


AMS 到 ActivityThread 的调用流程




上面注释 1 处调用了 AMS 的 startActivityAsUser 方法。


ActivityManagerService#startActivityAsUser()


@Override


public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {


enforceNotIsolatedCaller("startActivity");


userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "startActivity", null);


// TODO: Switch to user app stacks here.


//1


return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, bOptions, false, userId, null, null);


}


注释 1 处调用了 ActivityStarter 的 startActivityMayWait 方法。


frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java


ActivityStarter#startActivityMayWait()


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, IActivityManager.WaitResult outResult, Configuration config,Bundle bOptions, boolean ignoreTargetSecurity, int userId,IActivityContainer iContainer, TaskRecord inTask) {


...


doPendingActivityLaunchesLocked(false); //1


...


return err;


}


注释 1 调用了 doPendingActivityLaunchesLocked 方法。


ActivityStarter#doPendingActivityLaunchesLocked()


final void doPendingActivityLaunchesLocked(boolean doResume) {


while (!mPendingActivityLaunches.isEmpty()) {


final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);


final boolean resume = doResume && mPendingActivityLaunches.isEmpty();


try {


//1


final int result = startActivityUnchecked(pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null, null);


postStartActivityUncheckedProcessing(pal.r, result, mSupervisor.mFocusedStack.mStackId, mSourceRecord, mTargetStack);


} catch (Exception e) {


Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);


pal.sendErrorResult(e.getMessage());


}


}


}


注释 1 处调用 startActivityUnchecked 方法。


ActivityStarter#startActivityUnchecked()


private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,


IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,


int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {


...


if (mDoResume) {


mSupervisor.resumeFocusedStackTopActivityLocked(); //1


}


...


return START_SUCCESS;


}


注释 1 处调用了 ActivityStackSupervisor 的 resumeFocusedStackTopActivityLocked 方法。


frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java


ActivityStackSupervisor#resumeFocusedStackTopActivityLocked()


boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {


if (targetStack != null && isFocusedStack(targetStack)) {


return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); //1


}


final ActivityRecord r = mFocusedStack.topRunningActivityLocked();


if (r == null || r.state != RESUMED) {


mFocusedStack.resumeTopActivityUncheckedLocked(null, null);


}


return false;


}


注释 1 处调用了 ActivityStack 的 resumeTopActivityUncheckedLocked 方法。


frameworks/base/services/core/java/com/android/server/am/ActivityStack.java


ActivityStack#resumeTopActivityUncheckedLocked()


boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {


...


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); //1


} finally {


mStackSupervisor.inResumeTopActivity = false;


}


return result;


}


注释 1 处调用 resumeTopActivityInnerLocked 函数。


ActivityStack#resumeTopActivityInnerLocked()


private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {


...


// If the top activity is the resumed one, nothing to do.


if (mResumedActivity == next && next.state == ActivityState.RESUMED &&


mStackSupervisor.allResumedActivitiesComplete()) {


...


return false;


}


if (mResumedActivity != null) {


if (DEBUG_STATES) Slog.d(TAG_STATES,


"resumeTopActivityLocked: Pausing " + mResumedActivity);


pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause); //1


}


...


mStackSupervisor.startSpecificActivityLocked(next, true, false); //2


if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();


...


这个方法里面的内容很多。


注释 1 主要作用是将 mResumedActivity 暂停(Launcher 任务栈的 TopActivity),即进入 onPause 状态。


注释 2 调用了 ActivityStackSupervisor 的 startSpecificActivityLocked 函数启动指定的 AttivityRecored。


frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java


ActivityStackSupervisor#startSpecificActivityLocked()


void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {


//1


ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true);


r.task.stack.setLaunchTime(r);


if (app != null && app.thread != null) {


try {


if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) {


app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode, mService.mProcessStats);


}


realStartActivityLocked(r, app, andResume, checkConfig); //2


return;


} catch (RemoteException e) {


Slog.w(TAG, "Exception when starting activity " + r.intent.getComponent().flattenToShortString(), e);


}


}


//3


mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true);


}


ActivityStackSupervisor#getProcessRecordLocked()


final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {


if (uid == Process.SYSTEM_UID) {


// The system gets to run in any process. If there are multiple


// processes with the same uid, just pick the first (this


// should never happen).


SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);


if (procs == null) return null;


...


}


...


}


注释 1 处获取当前 Activity 所在的进程的 ProcessRecord,如果进程已经启动了,会执行注释 2 处的代码。否则执行注释 3 的代码。


注释 2 处调用 realStartActivityLocked 来启动应用程序。


注释 3 处调用 AMS 的 startProcessLocked 来启动应用程序进程,注意这里是应用程序进程,只有应用程序进程起来了,才能起应用程序。关于应用程序进程的启动我们可以看 Framework 学习(六)应用程序进程启动过程这篇文章。


ActivityStackSupervisor#realStartActivityLocked()


final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {


...


//1


app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume,mService.isNextTransitionForward(), profilerInfo);


...


return true;


}


这里的 app.thread 指的是 IApplicationThread,它的实现是 ActivityThread 的内部类 ApplicationThread,其中 ApplicationThread 继承了 ApplicationThreadNative,而 ApplicationThreadNative 继承了 Binder 并实现了 IApplicationThread 接口。


下面看从 AMS 到 ApplicationThread 的时序图:



ActivityThread 启动 Application 和 Activity


在应用程序进程启动时会创建 ActivityThread 实例。ActivityThread 作为应用程序进程的核心类,它是如何启动应用程序(Activity)的呢?


根据上文接着查看 ApplicationThread 的 scheduleLaunchActivity 方法:


frameworks/base/core/java/android/app/ActivityThread.java


ApplicationThread#scheduleLaunchActivity()


@Override


public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig, Configuration overrideConfig,


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;


r.overrideConfig = overrideConfig;


updatePendingConfiguration(curConfig);


sendMessage(H.LAUNCH_ACTIVITY, r); //1


}


会将启动 Activity 的参数封装成 ActivityClientRecord。


注释 1 处 sendMessage 方法向 H 类发送类型为 LAUNCH_ACTIVITY 的消息,并将 ActivityClientRecord 传递过去。


ApplicationThread#sendMessage()


private void sendMessage(int what, Object obj) {


sendMessage(what, obj, 0, 0, false);


}


private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {


if (DEBUG_MESSAGES) Slog.v(


TAG, "SCHEDULE " + what + " " + mH.codeToString(what)


  • ": " + arg1 + " / " + obj);


Message msg = Message.obtain();


msg.what = what;


msg.obj = obj;


msg.arg1 = arg1;


msg.arg2 = arg2;


if (async) {


msg.setAsynchronous(true);


}


mH.sendMessage(msg);


}


这里 mH 指的是 H,它是 ActivityThread 的内部类并继承 Handler。


ActivityThread.H


private class H extends Handler {


public static final int LAUNCH_ACTIVITY = 100;


public static final int PAUSE_ACTIVITY = 101;


...


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;//1


r.packageInfo = getPackageInfoNoCheck(


r.activityInfo.applicationInfo, r.compatInfo);//2


handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");//3


Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);


} break;


...


}


查看 H 的 handleMessage 方法中对 LAUNCH_ACTIVITY 的处理。


注释 1 处将传过来的 msg 的成员变量 obj 转换为 ActivityClientRecord。


在注释 2 处通过 getPackageInfoNoCheck 方法获得 LoadedApk 类型的对象并赋值给 ActivityClientRecord 的成员变量 packageInfo 。应用程序进程要启动 Activity 时需要将该 Activity 所属的 APK 加载进来,而 LoadedApk 就是用来描述已加载的 APK 文件。


在注释 3 处调用 handleLaunchActivity 方法。


ActivityThread#handleLaunchActivity()


private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {


...


Activity a = performLaunchActivity(r, customIntent); //1


if (a != null) {


r.createdConfig = new Configuration(mConfiguration);


reportSizeConf


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


igurations(r);


Bundle oldState = r.state;


//2


handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);


if (!r.activity.mFinished && r.startsNotResumed) {


performPauseActivityIfNeeded(r, reason);


if (r.isPreHoneycomb()) {


r.state = oldState;


}


}


} else {


try {


//3


ActivityManagerNative.getDefault() .finishActivity(r.token, Activity.RESULT_CANCELED, null,


Activity.DONT_FINISH_TASK_WITH_ACTIVITY);


} catch (RemoteException ex) {


throw ex.rethrowFromSystemServer();


}


}


}


注释 1 处的 performLaunchActivity 方法用来启动 Activity。


注释 2 处的代码用来执行 Activity 的 onResume 方法,将 Activity 的状态置为 Resume。


注释 3 如果该 Activity 为 null 则会通知 ActivityManager 停止启动 Activity。


ActivityThread#performLaunchActivity()


private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {


...


ActivityInfo aInfo = r.activityInfo; //1


if (r.packageInfo == null) {


r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,Context.CONTEXT_INCLUDE_CODE); //2


}


ComponentName component = r.intent.getComponent(); //3


...


Activity activity = null;


try {


java.lang.ClassLoader cl = r.packageInfo.getClassLoader();


activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent); //4


...


}


} catch (Exception e) {


...


}


try {


Application app = r.packageInfo.makeApplication(false, mInstrumentation); //5


...


if (activity != null) {


Context appContext = createBaseContextForActivity(r, activity); //6


...


}


//7


activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, r.embeddedID, r.lastNonConfigurationInstances, config, r.referrer, r.voiceInteractor, window);


...


if (r.isPersistable()) {


mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); //8


} else {


mInstrumentation.callActivityOnCreate(activity, r.state);


}


...


if (!r.activity.mFinished) {


activity.performStart(); //9


r.stopped = false;


}


...


mActivities.put(r.token, r); //10


}


return activity;


}


注释 1 处用来获取 ActivityInfo。


注释 2 处获取 APK 文件的描述类 LoadedApk。


注释 3 处获取要启动的 Activity 的 ComponentName 类,ComponentName 类中保存了该 Activity 的包名和类名。


注释 4 处根据 ComponentName 中存储的 Activity 类名,用类加载器通过反射来创建该 Activity 的实例。


注释 5 处用来创建 Application 对象,makeApplication 方法内部会调用 Application 的 onCreate 方法。该 Application 对象的唯一作用就是作为参数传递到 Activity 里,然后在 Activity 类中可以获得调用 getApplication 方法来获取 Application 对象。


注释 6 处用来创建要启动 Activity 的上下文环境 ContextImpl。


注释 7 处调用 Activity 的 attach 方法初始化 Activity,将 ContextImpl 对象注册到对应的 Activity 中,之后在 Activity 类中就可以使用 Context 的所有功能了。


注释 8 处会调用 Instrumentation 的 callActivityOnCreate 方法来启动 Activity。


注释 9 处用来执行 Activity 的 onStart 方法。


注释 10 处将启动的 Activity 加入到 ActivityThread 的成员变量 mActivities 中,其中 mServices 是 ArrayMap 类型。


先来看看注释 5 方法:


frameworks/base/core/java/android/app/LoadedApk.java


LoadedApk#makeApplication()


public Application makeApplication(boolean forceDefaultAppClass,


Instrumentation instrumentation) {


if (mApplication != null) { //1


return mApplication;


}


Application app = null;


...


try {


ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);


app = mActivityThread.mInstrumentation.newApplication(


cl, appClass, appContext); //2


} catch (Exception e) {


...


}


...


if (instrumentation != null) {


try {


instrumentation.callApplicationOnCreate(app); //3


} catch (Exception e) {


...


}


}


}


return app;


}


注释 1 判断当前应用是否是第一次创建 Application 对象,如果不是则直接返回 Application 对象,否则执行注释 2 创建第一个 Application 对象。目的是确保当前应用之创建了一个全局的 Application 对象。


注释 2 调用 Instrumentation 的 newApplication()方法创建 Application。


注释 3 调用 Instrumentation 的 callApplicationOnCreate()。


frameworks/base/core/java/android/app/Instrumentation.java


Instrumentation#newApplication()


public Application newApplication(ClassLoader cl, String className, Context context)


throws InstantiationException, IllegalAccessException,


ClassNotFoundException {


return newApplication(cl.loadClass(className), context);


}


static public Application newApplication(Class<?> clazz, Context context)


throws InstantiationException, IllegalAccessException,


ClassNotFoundException {


Application app = (Application)clazz.newInstance(); //1


app.attach(context); //2


return app;


}


注释 1 简单粗暴,通过反射创建一个 Application 实例。


注释 2 处调用 Application 的 attach 方法初始化 Application,将 ContextImpl 对象注册到对应的 Application 中,之后在 Application 类中就可以使用 Context 的所有功能了。


Instrumentation#callApplicationOnCreate()


public void callApplicationOnCreate(Application app) {


app.onCreate();


}


这样 Application 的 onCreate()方法也得到执行。


现在已经有了 Application 且它的 onCreate()方法也得到执行。但 Activity 只是被 ClassLoader 装载了,onCreate()还没有调起来。回到 ActivityThread 的 performLaunchActivity()方法,看看注释 8 的方法:


Instrumentation#callActivityOnCreate()


public void callActivityOnCreate(Activity activity, Bundle icicle) {


prePerformCreate(activity);


activity.performCreate(icicle); //1


postPerformCreate(activity);


}


注释 1 会调用 Activity 的 performCreate 方法。


frameworks/base/core/java/android/app/Activity.java


Activity#performCreate()


final void performCreate(Bundle icicle) {


restoreHasCurrentPermissionRequest(icicle);


onCreate(icicle); //1


mActivityTransitionState.readState(icicle);


performCreateCommon();


}


注释 1 会调用 Activity 的 onCreate 方法,这样 Activity 就启动了,即应用程序就启动了。


下面看从 ApplicationThread 到 Activity 的时序图:



image


总体流程




1.Launcher 通过 Binder 机制通知 AMS 启动一个 Activity.


2.AMS 使 Launcher 栈最顶端 Activity 进入 onPause 状态.


3.AMS 通知 Process 使用 Socket 和 Zygote 进程通信,请求创建一个新进程.


4.Zygote 收到 Socket 请求,fork 出一个进程,并调用 ActivityThread#main().


5.ActivityThread 通过 Binder 通知 AMS 启动应用程序.


6.AMS 通知 ActivityStackSupervisor 真正的启动 Activity.


7.ActivityStackSupervisor 通知 ApplicationThread 启动 Activity.

评论

发布
暂无评论
Android Framework学习笔记(五)应用程序启动过程