源码
关键类说明
1、ActivityRecord
Activity栈中的一个节点,用于展示一个Activity
它集成了WindowToken实现了WindowManagerService中的一个接口
既然如此顺便看看WindowToken吧
ActivityTaskSupervisor
用来替代ActivityStackSupervisor
Instrumentation
这东西是ActivityThread中的一个变量
它可以作为一个测试框架的根基,因为它是先于我们的Application和Activity启动的,所以它可以监听到我们创建Activity和Application操作。
android是支持自定义Instrumentation的,可以通过继承Instrumentation重写里面的方法实现监听
顺手找了一篇参考文章:blog.csdn.net/weixin_4235…
启动过程源码
- startActivity方法
- startActivityForResult方法
最终会走到Instrumentation.execStartActivity方法
- Instrumentation.execStartActivity方法
ActivityTaskManager.getService()返回结果就是IActivityTaskManager类型
需要说明的是本方法中最后一步调用的checkStartActivityResult方法可以根据返回的result判断启动activity的结果
checkStartActivityResult方法的实现可以查看 附1中内容
这里的ActivityTaskManager.getService()要说明一下,它最终调用到了ActivityTaskManager中的单例,然后获取binder调用接口
所以这里的ActivityTaskManager.getService().startActivity实际上就是ActivityTaskManagerService.startActivity
- ActivityTaskManagerService.startActivity
- startActivityAsUser
- ActivityStarter.execute
这里负责执行启动逻辑
- executeRequest
代码巨长,关键代码再结尾处startActivityUnchecked
- startActivityUnchecked
- startActivityInner
- Task.startActivityLocked
- Task.resumeTopActivityUncheckedLocked
- ActivityTaskSupervisor.startSpecificActivity
- ActivityTaskSupervisor.realStartActivityLocked
- ClientTransaction.addCallback
- ClientLifecycleManager.scheduleTransaction
mService.getLifecycleManager().scheduleTransaction(clientTransaction)
- ClientTransaction.schedule
- IApplicationThread.scheduleTransaction
实际类型是ApplicationThread.scheduleTransaction
- ApplicationThread.H.sendMessage()
- TransactionExecutor.execute
mTransactionExecutor.execute(transaction);
- ActivityThread.handleLaunchActivity
- ActivityThread.performLaunchActivity
createBaseContextForActivity方法的说明见:附2
下图中的newActivity用来创建Activity对象,实际上如果我们的Application如果没有创建,它会连带Application一起创建。但是似乎这个Application的创建并没有意义,只是个站位作用。
下图中appContext.setOuterContext(activity);方法,将我们的的activity对象赋值给ContextImpl,目的是让他们产生关联。
在Activity.attach方法中,只做了一件事,就是调用onAttachFragment方法来初始化Fragment
makeApplication方法的说明见附3
- ActivityThread.callActivityOnCreate方法
这个方法过后逻辑终于又转到了Activity中
- 最终方法会调用到performCreate方法
本节参考:www.jianshu.com/p/e875f8bde…
总结
Activity启动过程,首先会调用startActivity,最终一定会调用到Activity.startActivityForResult方法。然后会调用Instrucment.execStartActivity方法并且会获取调用ActivityThread.getApplicationThread方法获取IApplicationThread对象,IApplicationThread是一个Binder对象,它是应用进程和atms沟通的桥梁。
调用完execStartActivity方法后,会获取atms实例,然后调用atms.startActivity方法,这就完成了应用和atms的通信,程序逻辑转换到了atms中。在atms进行一大堆操作后会调用IApplicationThread的方法回调到应用进程,执行activity页面的启动工作。
atms处理完成后会调用ApplicationThread.scheduleTransaction方法,因为IApplicationThread是一个Binder对象,所以这个方法将逻辑从atms中转回到应用逻辑中。
回到应用中处理的逻辑是这样的,首先通过ActivityThread.H发送一条handler消息,告诉主线程需要启动activity。最终会将逻辑调用到ActivityThread.handleLaunchActivity方法,在Instrumentaction中使用反射创建Activity对象实例,并调用Activity.attach方法,后面会再次调用到Instrumentation.callActivityOnCreate方法,从这里就进入了activity的生命周期了。
activity的启动过程一共有两次Binder通信,
- 用于进程调用ActivityTaskManagerService.startActivity,代码进入atms进程中执行
- ClientTransaction类中IApplicationThread.scheduleTransaction,atms调用应用进程的Binder让Activity启动逻辑回到应用进程
附
1、Instrumentation.checkStartActivityResult方法
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static void checkStartActivityResult(int res, Object intent) { if (!ActivityManager.isStartResultFatalError(res)) { return; } switch (res) { case ActivityManager.START_INTENT_NOT_RESOLVED: case ActivityManager.START_CLASS_NOT_FOUND: if (intent instanceof Intent && ((Intent)intent).getComponent() != null) throw new ActivityNotFoundException( "Unable to find explicit activity class " + ((Intent)intent).getComponent().toShortString() + "; have you declared this activity in your AndroidManifest.xml?"); throw new ActivityNotFoundException( "No Activity found to handle " + intent); case ActivityManager.START_PERMISSION_DENIED: throw new SecurityException("Not allowed to start activity " + intent); case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT: throw new AndroidRuntimeException( "FORWARD_RESULT_FLAG used while also requesting a result"); case ActivityManager.START_NOT_ACTIVITY: throw new IllegalArgumentException( "PendingIntent is not an activity"); case ActivityManager.START_NOT_VOICE_COMPATIBLE: throw new SecurityException( "Starting under voice control not allowed for: " + intent); case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION: throw new IllegalStateException( "Session calling startVoiceActivity does not match active session"); case ActivityManager.START_VOICE_HIDDEN_SESSION: throw new IllegalStateException( "Cannot start voice activity on a hidden session"); case ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION: throw new IllegalStateException( "Session calling startAssistantActivity does not match active session"); case ActivityManager.START_ASSISTANT_HIDDEN_SESSION: throw new IllegalStateException( "Cannot start assistant activity on a hidden session"); case ActivityManager.START_CANCELED: throw new AndroidRuntimeException("Activity could not be started for " + intent); default: throw new AndroidRuntimeException("Unknown error code " + res + " when starting " + intent); } } 复制代码
2、ActivityThread.createBaseContextForActivity是如何创建上下文的
3、ActivityThread.performLaunchActivity方法中的makeApplication是如何工作的
- makeApplication方法
makeApplication方法在LoadedApk中
下图中的mInstrumentation.newApplication是下面要看的重点
这里的callApplicationOnCreate是下一步要看的重点
- Instrumentation.newApplication创建Application对象
这一步可以跳过,直接看第3步 Application.attach方法主要是调用attachBaseContext方法,并且将LoadedApk对象赋值给Application。
- Instrumentation.callApplicationOnCreate方法
这个方法就更简单了,直接就调用Application.onCreate,这样Application的创建和launch就结束了
4、流程图
找到一张不错的代码流程图,是低于安卓10版本的流程图,和高于android10的流程90%相似,所以拿来主义了。
流程图出处见结尾参考文章
Intent传输数据不能超过1mb原因分析
- 由于Activity通过intent传值,是通过App进程将intent携带的数据传输到AMS进程,最终通过Binder事务缓冲区完成数据传输
- 目前Binder事务缓冲区的大小固定有限,目前为1MB,进程中正在处理的所有事务共享
- 由于此限制是进程级别而不是Activity级别的限制,因此这些事务包括应用中的所有 binder 事务,超过大小限制时,将引发TransactionTooLargeException。
见参考4
5、onCreate后的生命周期
主要是onResume,参见WindowManager中的描述