赞
踩
Activity栈中的一个节点,用于展示一个Activity
它集成了WindowToken实现了WindowManagerService中的一个接口
既然如此顺便看看WindowToken吧
用来替代ActivityStackSupervisor
这东西是ActivityThread中的一个变量
它可以作为一个测试框架的根基,因为它是先于我们的Application和Activity启动的,所以它可以监听到我们创建Activity和Application操作。
android是支持自定义Instrumentation的,可以通过继承Instrumentation重写里面的方法实现监听
顺手找了一篇参考文章:https://blog.csdn.net/weixin_42355665/article/details/117661233
最终会走到Instrumentation.execStartActivity方法
ActivityTaskManager.getService()返回结果就是IActivityTaskManager类型
需要说明的是本方法中最后一步调用的checkStartActivityResult方法可以根据返回的result判断启动activity的结果
checkStartActivityResult方法的实现可以查看 附1中内容
这里的ActivityTaskManager.getService()要说明一下,它最终调用到了ActivityTaskManager中的单例,然后获取binder调用接口
所以这里的ActivityTaskManager.getService().startActivity实际上就是ActivityTaskManagerService.startActivity
这里负责执行启动逻辑
代码巨长,关键代码在结尾处startActivityUnchecked
mService.getLifecycleManager().scheduleTransaction(clientTransaction)
实际类型是ApplicationThread.scheduleTransaction
mTransactionExecutor.execute(transaction);
createBaseContextForActivity方法的说明见:附2
下图中的newActivity用来创建Activity对象,实际上如果我们的Application如果没有创建,它会连带Application一起创建。但是似乎这个Application的创建并没有意义,只是个站位作用。
下图中appContext.setOuterContext(activity);方法,将我们的的activity对象赋值给ContextImpl,目的是让他们产生关联。
在Activity.attach方法中,只做了一件事,就是调用onAttachFragment方法来初始化Fragment
makeApplication方法的说明见附3
这个方法过后逻辑终于又转到了Activity中
本节参考:https://www.jianshu.com/p/e875f8bdedef
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启动逻辑回到应用进程
@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); } }

makeApplication方法在LoadedApk中
下图中的mInstrumentation.newApplication是下面要看的重点

这里的callApplicationOnCreate是下一步要看的重点

这一步可以跳过,直接看第3步
Application.attach方法主要是调用attachBaseContext方法,并且将LoadedApk对象赋值给Application。

这个方法就更简单了,直接就调用Application.onCreate,这样Application的创建和launch就结束了

找到一张不错的代码流程图,是低于安卓10版本的流程图,和高于android10的流程90%相似,所以拿来主义了。
流程图出处见结尾参考文章

见参考4
主要是onResume,参见WindowManager中的描述
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。