在进程之间,咱们都是通过binder来通信,四大组件与AMS来来回回的通信,要是能了解一下,就会发现Android一些东西都是能够联系起来,会有一种豁然开朗的感觉。
在APP侧,进行一些操作,比如AMS给Activity发送的所有消息,以及给其它三大组件发送的所有消息,都会在ActivityThread类的内部类大H经过。为啥要单独说呢,因为activity继承于context,而其他三大组件在Context中有抽象方法,具体在ContextImpl实现,在ConetextWrapper回调接口。
咱们可以具体了解一下APP的启动过程,留下印象即可:
APP启动流程
- Launcher->AMS:
Launcher向AMS发送一个跨进程通信,通过AMN/AMP,告诉AMS,我要启动别的App
Instrumentation的execStartActivity方法 Instrumentation绝对是Adnroid测试团队的最爱,因为它可以帮我们启动Activity。 回到我们的App启动过程来,在Instrumentation的execStartActivity方法中 Activity把数据借助Instrumentation,传递给ActivityManagerNative
我们每次跳转activity都会用到startActivity或者startActivityForResult,最终都会跳转到startActivityForResult
startActivityForResult->Instrumentation.execStartActivity->AMN.getDefault
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
// 这里就是我们的仪表盘Instrumentation了,帮助我们启动Activity
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
// 源代码注释说了一大堆,翻译一下就是把这个activity隐藏了,直到下个activity finish收到结果
mStartedActivity = true;
}
......
AMN(ActivityManagerNative)有点像Stub,AMN继承于AMP,AMP(ActivityManagerProxy)类似于Proxy,他们都实现了IActivityManager接口(说它是aidl.java不过分吧)
- AMS->launcher:
client AMS发消息schedulePauseActivity()->Service launcher通过ApplicationThread类来实现来实现,这是ActivityThread的内部类
private class ApplicationThread extends IApplicationThread.Stub {
private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
public final void scheduleReceiver(Intent intent, ActivityInfo info,
CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
boolean sync, int sendingUser, int processState) {
可以很清楚的看到,IApplicationThread类似于我们的aidl接口
- launcher->AMS
APT接收到来自AMS的消息后,就调用ActivityThread的sendMessage方法,向Launcher的主线程消息队列发送一个PAUSE_ACTIVITY消息。
前面说过,ActivityThread就是主线程中H发送消息,让launcher中的Activity进入Stop休眠
- AMS->APP
AMS调用Process.start(),指定ActivityThread的main函数作为入口
- APP -> AMS
到APP这边,就立即先创建ActivityThread(主线程),然后进入main函数里面,main()里面有蓝牙啊文件啊媒体啊等等的初始化,当然最重要的是创建了主线程的looper,网上说还有生成Application,我没找到。然后把ActivityThread对象发送给AMS进行记录
- AMS->APP:
AMS把传入的ActivityThread对象,转为一个ApplicationThread对象,用于以后和这个App跨进程通信,AMS传递APP中要启动的Activity
- APP
APP接收到消息,仍然在H的handleMessage方法的switch语句中处理,只不过,这次消息的类型是LAUNCH_ACTIVITY:
handleLaunchActivity方法都做哪些事呢?
- 通过Instrumentation的newActivity方法,创建出来要启动的Activity实例。
- 为这个Activity创建一个上下文Context对象,并与Activity进行关联。
- 通过Instrumentation的callActivityOnCreate方法,执行Activity的onCreate方法,从而启动Activity。
同进程内:
1)ActivityA向AMS发送一个启动ActivityB的消息。
2)AMS保存ActivityB的信息,然后通知App进入onPaused。
3)ActivityA进入onPaused,然后通知AMS。
4)AMS发现ActivityB所在的进程就是ActivityA所在的进程,所以不需要重新启动新的进程,然后发送给App消息,启动ActivityB。
5)App启动ActivityB。