前言
应用启动流程简单分为三个模块,其中最后由ActivityThread启动Activity是常见的面试高频问题,所以前面两个部分简单整理(有空再上源码分析),第三部分从源码分析,讲的比较详细。
一.Launcher请求ActivityManageService
1.点击图标,调用 launcher类 的 startActivitySafely 方法,其中调用了内部方法 startActivity,
2.方法里设置了 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);这样根Activity会在新的任务栈中启动,然后调用了activity的 startActivity方法
3.startActivity 又调用 startActivityForResult 方法
4.startActivityForResult 中判断mParent 是否为空 ,因为是根Activity还没创建,所以会走为空的分支 ,调用 Instrumentation的 execStartActivity 方法(不为空 走startActivityFromChild 方法 这个方法最终还是调用 Instrumentation的 execStartActivity 方法 具体情况后续分析)
5.看到 nstrumentation的 execStartActivity 方法 ,首先会调用ActivityManagerNative的getDefault来获取ActivityManageService(以后简称为AMS)的代理对象(AMP),接着调用它的startActivity方法。
6.AMP是 ActivityManagerNative 的内部类 ,startActivity方法,通过IBinder对象mRemote向AMS发送一个START_ACTIVITY_TRANSACTION类型的进程间通信请求。那么服务端AMS就会从Binder线程池中读取我们客户端发来的数据,最终会调用ActivityManagerNative的onTransact方法中执行,
7.onTransact中会调用AMS的startActivity方法
二.ActivityManageService到ApplicationThread的调用流程
1.AMS的startActivity方法中return了startActivityAsUser方法:
2.startActivityAsUser方法中又return了mActivityStarter的startActivityMayWait方法
3.又调用了startActivityLocked方法
4.接着又调用startActivityUnchecked方法:
5.startActivityUnchecked方法中调用了ActivityStackSupervisor类型的mSupervisor的resumeFocusedStackTopActivityLocked方法
6.在注释1处又调用了ActivityStack类型mFocusedStack的resumeTopActivityUncheckedLocked方法:
7.紧接着查看ActivityStack的resumeTopActivityInnerLocked方法
8.最后运行 realStartActivityLocked方法 ,app.thread指的是IApplicationThread,它的实现是ActivityThread的内部类ApplicationThread,其中ApplicationThread继承了ApplicationThreadNative,而ApplicationThreadNative继承了Binder并实现了IApplicationThread接口。最后调用了ApplicationThread的scheduleLaunchActivity方法
三.ActivityThread启动Activity(重点来了)
ApplicationThread的scheduleLaunchActivity方法,scheduleLaunchActivity方法会将启动Activity的参数封装成ActivityClientRecord,调用sendMessage传递参数
frameworks/base/core/java/android/app/ActivityThread.java:
@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);//传递参数
}
sendMessage方法向H类发送类型为LAUNCH_ACTIVITY的消息,并将ActivityClientRecord 传递过去,
frameworks/base/core/java/android/app/ActivityThread.java:
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
...
mH.sendMessage(msg);
}
这里mH指的是H,它是ActivityThread的内部类并继承Handler,H的代码如下所示。
frameworks/base/core/java/android/app/ActivityThread.java
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;
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;
...
查看H的handleMessage方法中对LAUNCH_ACTIVITY的处理,在注释1处将传过来的msg的成员变量obj转换为ActivityClientRecord。
在注释2处通过getPackageInfoNoCheck方法获得LoadedApk类型的对象并赋值给ActivityClientRecord 的成员变量packageInfo 。应用程序进程要启动Activity时需要将该Activity所属的APK加载进来,而LoadedApk就是用来描述已加载的APK文件。
在注释3处调用handleLaunchActivity方法,代码如下所示。
frameworks/base/core/java/android/app/ActivityThread.java
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
...
Activity a = performLaunchActivity(r, customIntent);//1
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);//2
if (!r.activity.mFinished && r.startsNotResumed) {
performPauseActivityIfNeeded(r, reason);
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
} else {
try {
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 的状态置为Resume。如果该Activity为null则会通知ActivityManager停止启动Activity。来查看performLaunchActivity方法做了什么:
frameworks/base/core/java/android/app/ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
ActivityInfo aInfo = r.activityInfo;//1获取ActivityInfo
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);//2获取APK文件的描述类LoadedApk
}
ComponentName component = r.intent.getComponent();//3获取要启动的Activity的ComponentName类
...
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);//4用类加载器来创建该Activity的实例
...
}
} catch (Exception e) {
...
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);//5创建Application
...
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);//6创建要启动Activity的上下文环境
...
}
/**
*7用Activity的attach方法初始化Activity
*/
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调用Instrumentation的callActivityOnCreate方法来启动Activity
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
}
return activity;
}
注释1处用来获取ActivityInfo,在注释2处获取APK文件的描述类LoadedApk。注释3处获取要启动的Activity的ComponentName类,ComponentName类中保存了该Activity的包名和类名。注释4处根据ComponentName中存储的Activity类名,用类加载器来创建该Activity的实例。注释5处用来创建Application,makeApplication方法内部会调用Application的onCreate方法。注释6处用来创建要启动Activity的上下文环境。注释7处调用Activity的attach方法初始化Activity,attach方法中会创建Window对象(PhoneWindow)并与Activity自身进行关联。注释8处会调用Instrumentation的callActivityOnCreate方法来启动Activity:
frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);//1
postPerformCreate(activity);
}
注释1处调用了Activity的performCreate方法,代码如下所示。
frameworks/base/core/java/android/app/Activity.java
final void performCreate(Bundle icicle) {
restoreHasCurrentPermissionRequest(icicle);
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
performCreate方法中会调用Activity的onCreate方法,这样Activity就启动了,即应用程序就启动了。
有想学习Android的程序员,或者是想进阶提升的成为Android高级架构师的程序员都可以点击【Android高级工程师进阶学习】加入我们的圈子领取资料和我们一起吧学习交流!下面是我在开发12年以来,整理搜集的一些资料,不多但是好在比较系统有需要的朋友,可以自行领取!
-
Android进阶学习全套手册
关于实战,我想每一个做开发的都有话要说,对于小白而言,缺乏实战经验是通病,那么除了在实际工作过程当中,我们如何去更了解实战方面的内容呢?实际上,我们很有必要去看一些实战相关的电子书。目前,我手头上整理到的电子书还算比较全面,HTTP、自定义view、c++、MVP、Android源码设计模式、Android开发艺术探索、Java并发编程的艺术、Android基于Glide的二次封装、Android内存优化——常见内存泄露及优化方案、.Java编程思想 (第4版)等高级技术都囊括其中。
-
Android高级架构师进阶知识体系图
关于视频这块,我也是自己搜集了一些,都按照Android学习路线做了一个分类。按照Android学习路线一共有八个模块,其中视频都有对应,就是为了帮助大家系统的学习。接下来看一下导图和对应系统视频吧!!!
-
Android对标阿里P7学习视频
-
BATJ大厂Android高频面试题
这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等
网友评论