共计 3571 个字符,预计需要花费 9 分钟才能阅读完成。
考查要点:
- 启动 Activity 会经验哪些生命周期回调
- 冷启动大抵流程,波及哪些组件,通信过程是怎么样的?
- Activity 启动过程中,生命周期回调的原理?
总的流程图:
1. 过程 A 与 AMS 的交互过程
此处以跨过程启动 Activity 剖析一下源码流程:
-
A 调用 startActivity 时,须要与 AMS 交互,此时须要须要获取到 AMS 的代理对象 Binder 也就是上图的 AMP,通过 ActivityManagerNative.getDefault()取得,并调用 AMP 的 startActivity 办法,而后会通过 mRemote.transact 办法进行 Binder 通信,在 AMS 的 onTransact 办法外面会获取到申请的 Activity 参数信息:
mRemote.transact(START_ACTIVITY_TRANSACTION,data,reply,0); ... @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags){switch(code){ case START_ACTIVITY_TRANSACTION:{startActivity(app,callingPackage,intent,...) } } }
- AMS 外面的 startActivity 办法最次要会去调用 startSpecificActivityLocked 函数,在此函数外面会去判断指标过程是否曾经存在,并且指标向 AMS 注册过它本人的 ApplicationThread 也就是上图 ATP 代理对象,如果这两个条件都满足会去调用 realStartActivityLocked 办法,这个办法咱们前面再看。如果上述条件不满足时,会去调用 mService.startProcessLocked(r.processName,…)办法启动过程。
2. AMS 启动指标过程 B
![](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/2/7/1702043547d09967~tplv-t2oaga2asx-watermark.image)
- startProcessLocked 办法首先调用 Process.start(“android.app.ActivityThread”,)办法会向 Zygote 发送一个启动过程的申请,并告知 Zygote 过程启动之后,加载 ActivityThread 这个类的入口 main 函数,启动实现后返回过程的 pid,并向 AMS 的 Handler 发送一个提早音讯,为的是要求指标过程启动后,10 秒钟内须要向 AMS 报告,不然的话 AMS 就会革除指标过程的相干信息。
- Process.start 办法会去调用 startViaZygote(processClass,)函数,这个函数次要做了两件事,一件就是关上通往 Zygote 的 Socket,第二件事就是通过 Socket 发送启动过程参数。
- Zygote 端次要逻辑是在 runOnce 函数,函数内调用 Zygote.forkAndSpecialize(…)创立子过程,创立实现之后就别离在父过程和子过程外面做各自的事件
- 父过程通过 hanleParentProc(pid)把子过程的 pid 通过 Socket 发送给 AMS
- 子过程调用 handleChildProc 函数,做一些通用的初始化,比方启用 Binder 机制;执行应用程序的入口函数,也就是 ActivityThread 的 Main 函数
- ActivityThread 的 main 函数,外面会创立一个 ActivityThread 对象,并调用 thread.attach(false),为的是向 AMS 报到,下面第一条外面有提到。
-
attach 办法外面,其实是一个跨过程的调用,首先通过
IActivityManager mgr = ActivityManagerNative.getDefault();
获取到 AMS 的 Binder 代理对象,而后调用
mgr.attachApplication(mAppThread);
mAppThread 是利用端的一个 Binder 对象 ApplicationThread,也就是最下面一张图的 ATP,这样 AMS 端就能够调用利用端了。
-
attachApplication 办法外面,最次要有两个办法,一个是通过传入的 ApplicationThread 对象,调用 bindApplication 初始化 Application 对象,另一个就是通过
mStactSupervisor.attachApplicationLoacked(app);
初始化挂起的 Activity 对象。
-
在 attachApplicationLoacked 函数里,会调用
ActivityRecord hr = stack.topRunningActivityLocked(null);
其中要明确 AMS 外面有两个栈,一个是 Launch 桌面栈,一个就是非桌面栈 mFocusedStack, 此处的 stack 就是 mFocusedStack,它会将栈顶的 ActivityRecord 返回进去,咱们的指标 Activity 早就搁置在了栈顶,只是始终没有初始化。而后调用
realStartActivityLocked(hr,app,true,true);
办法,来启动 Activity,如果咱们不是启动另外一个过程,而是同一过程,那么这第二大部分就不会存在了,而是间接调用 realStartActivityLocked 办法。
3. 利用端 Activity 启动的几个步骤
-
realStartActivityLocked 函数会调用 app.thread.scheduleLaunchActivity(new Intent(r.intent),…); 也就是通过之前注册的 Binder 对象 ATP,调用 scheduleLaunchActivity 函数,在 scheduleLaunchActivity 函数外面:
ActivityClientRecord r = new ActivityClientRecord(); ... sendMessage(H.LAUNCH_ACTIVITY,r);
封装了一个 ActivityClientRecord 音讯,而后丢到主线程的 Handler(mH)里。
-
在主线程外面
final ActivityClientRecord r =(ActivityClientRecord)msg.obj ; r.packageInfo = getPackageInfoNoCheck(...); handleLaunchActivity(r,null);
getPackageInfoNoCheck 函数次要是用来生成一个 LoadedApk 对象,它用来保留咱们的 apk 信息,因为前面咱们须要一个 ClassLoader 去加载 Apk 外面的 Activity 类,所以这里提前准备好。
- handleLaunchActivity 外面分为两个局部,一个是 performLaunchActivity 函数,一个是 handleResumeActivity 函数。
-
performLaunchActivity
Activity activity = mInstrumentation.newActivity(...); // 返回之前创立好的 Application app = r.packageInfo.makeApplication(false,mInstrumentation); // 生成 ContextImpl Context appContext = createBaseContextForActivity(r,activity); // 给 activity 绑定上下文和一些初始化的工作, 如 createPhoneWindow activity.attach(appContext,...); mInstrumentation.callActivityOnCreate(activity,r.state); // 生命周期的 OnCreate activity.performStart(); // 生命周期的 OnStart return activity
-
handleResumeActivity:
-> r.activity.performResume() -> mInstrumentation.callActivityOnResume(this); -> activity.onResume()
相干视频举荐
【安卓面试合集】startActivity 面试点 01
Android(安卓)开发零根底从入门到精通
本文转自 https://juejin.cn/post/6844904058688372750,如有侵权,请分割删除。