Activity的启动流程
公众号
面试官:说说 startActivity 吧
🤔️:startActivity 主要就是应用进程与 system_server 进程的 AMS 通信,AMS 是实际来管理 Activity 组件的,负责处理启动模式,维护 Activity 栈等工作。startActivity 的大概流程就是由应用进程 IPC 调用到 AMS,AMS 处理完这些工作后再 IPC 回到应用进程,创建 Activity 的实例,回调 Activity 的生命周期。
面试官:通过什么实现跨进程的呢?
🤔️:都是通过 AIDL 接口,App 进程到 systemserver 进程是通过 IActivityServerManager.aidl ,systemserver 到 App 进程通过 IApplicationThread.aidl
面试官:startActivity 时前后 Activity 的生命周期是怎样的?
🤔️:旧 Activity 的 onPause 会先执行,然后新 Activity 依次执行 onCreate、onStart、onResume,随后再执行旧 Activity 的 onStop...
面试官:旧 Activity 的 onPause 一定会先执行吗,为什么?
🤔️:这主要是 AMS 来控制的,它会先后将前一个 Activity 的 onPause 事务和新 Activity 的启动事务发送给 App 进程,而在 App 端由 IApplicationThread.aidl 接受到后,会入队到 ActivityThread.H 的消息队列中,这个也是主线程消息队列,在队列上自然就实现了先后顺序的控制
面试官:了解插件化吗,知道怎么启动一个插件中的 Activity 吗?
🤔️:主要需要解决的问题是 Activity 未在 manifest 中注册的问题,因为在 AMS 中会检查 Activity 是否注册,而这个检查逻辑处于 systemserver 进程,我们是无法 hook 的,可以在 manifest 中提前注册一个占位 Activity,然后 startActivity 时进入到 systemserver 进程之前,hook 把未注册的 Activity 改为占位 Activity,AMS 检测就可以通过,然后再回到 App 进程后,把这个占位 Activity 再换成插件 Activity
1.从本质来看,它不是一个线程,而是一个Java类;
2.需要在主线程的方法中被运行;
3.运行时,首先调用main方法,其中也会调用:OnAttatch,loop方法;
4.AMS--->ActivityManagerService;
5.ActivityManagerService;
5.一个线程中,只有一个Looper对象;
ActivityInfo 也是对Activity信息的描述,如主题,权限,启动方式,任务栈等
– ActivityRecord:可以从它的类命名知道,这个记录Activity信息的类,主要记录一个Activity的所有信息。一个ActivityRecord只能对应一个Activity,但是一个Activity在系统中可以存在多份实例,所以一个Activity可以对应多个ActivityRecord记录
– TaskRecord:TaskRecord由一个或者多个ActivityRecord组成,TaskRecord就是常说的任务栈,用来记录一个task里面的调用Activity的相关信息
– ActivityStack:是用来管理TaskRecord的,一个ActivityStack会包含多个TaskRecord
1、Application的创建。
2、生命周期的管理。
3、启动Activity。
ActivityManagerNative是远程代理对象。通过ActivityManagerNative来操纵ActivityManagerService进行通信。客户端需要和ActivityManagerService进行通信,但是它们在不同的进程中,需要进行跨进程间进行通信,底层是用Binder实现。
H类(Handler类的子类)会处理大量的ActivityManagerServer跨进程发送过来的消息,如启动Activity,暂停Activity等等
Activity的attach方法实现了与Window对象的关联
Activity中的Context对象向外关联了Activity本身
ContextImpl appContext = ContextImpl.createActivityContext(this,r.packageInfo,r.token);
appContext.setOuterContext(activity);
Activity中的Context对象是每个Activity中自己的ContextImpl 类的实例对象,与Application中的Context不是同一个对象
Application 对象创建完成后会通过mInstrumentation调用自己的onCreate生命周期方法
window 给自己这只WindowManager对象
WindowManager 对象通过(WindowManager)context.getSystemService(Context.WINDOW_SERVICE)获得
DecorView 继承自FrameLayout的View
Activity的attach方法源码解读
将Context对象attachBaseContext(context);
setContentView方法源码解析
调用PhoneWindow的setContectView
getWindow().setContentView
instrumentation.callApplicationOnCreate(app);
'app.oncreate()'
Application的真实创建过程
通过反射创建并将ContextImpl attach给自己
Application app = (Application) clazz.newInstance();
app.attach(context);
ContextImpl对象的创建时在makeApplication方法中创建的
通过ActivityThread中的Instrumentation的newApplication方法创建
Application对象并关联了ContextImpl对象
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread,this);
app = mActivityThread.mInstrumentation.newApplication(cl,appClass,appContext)
Application 的创建位置
Application app = r.packageInfo.makeApplication(false,mInstrumentation)
Activity的创建
通过类加载器加载完整的Activity类名反射创建Activity的类实例
cl.loadClass(className).newInstance();
Activity的创建机制是通过Java的反射机制创建的
handleLaunchActivity调用performLaunchActivity方法创建Activity对象
ActivityThread中的handleLaunchActivity方法中就启动、创建第一个Activity的
在Activity的performCreate中调用自己的onCreate方法
mH当中的handleResumeActivity方法处理ActivityManagerService返送的消息
Activity的performResume()方法通过mInstrumentation.callActivityOnResume(this)方法调用到Activity的onResume()方法
WindowManager 接口,继承与ViewManager接口
调用Activity的onResume方法后View并没有立即被显示在屏幕上
而是执行到mWindow.addView(decor)时
WindowManagerImpl是WindowManager的真实实现类
WindowManagerGlobal 类是具体实现对Window的管理
WindowManagerGlobal中创建了ViewRootImpl 对象root
ViewRootImpl是管理每一View的,是负责与远程的ActivityManagerServer进行交互的
ViewRootImpl 对象的创建
root = ViewRootImpl(view.getContext(), display);
W extends IWindow.Stub
W的对象实现了与远程ActivityManagerServer的交互
ViewRootImpl 的setView方法实现与要显示的View进行关联
每个View都有一个Parent,此Parent就是ViewRootImpl,ViewRootImpl负责View的绘制
当Activity的onResume 执行后,程序继续向后执行直到执行了Activity的makeVisible()时View才真正的显示到了屏幕上
mDecor.setVisibility(View.VISIBLE);
通过ActivityManagerNative.getDefault().activityResumed(token);
通知远程的ActivityManagerServer当前Activity为可见状态
destory实际并没有直接销毁掉activity (8.1源码)
通过performDestroyActivity()执行相应的生命周期方法performPauseActivityIfNeeded()、callActivityOnStop()、callActivityOnDestroy和移除它的IBinder
通过WindowManager的实现类WindowManagerImpl调用removeViewImmediate(),拿到activity的实际控制类ViewRootImpl对象将他的父窗口(父布局)的指定分派为null
将activity的content清理
Activity的启动流程
开发中我们会调用startActivity来启动一个Activity,最终会调到 startActivityForResult : Instrumentation 是Android系统里面的一套控制方法或者“钩子”。这些钩子可以在正常的生命周期(正常是由操作系统控制的)之外控制Android控件的运行。 Application和Activity的所有生命周期中,都会先调用Instrumentation提供的相应方法(如callActivityOnCreate,callApplicationOnCreate,newActivity,callActivityOnNewIntent) Instrumentation.execStartActivity ActivityTaskManager.getService()返回了一个IActivityTaskManager,拿到的是ATMS的代理对象,跨进程调用了ATMS的startActivity方法。 ActivityStarter.startActivityMayWait ActivityStarter中做了一系列的调用(收集Intent信息,处理startActivityForResult,做一些校验判断等),最终进入startActivityUnchecked。 startActivityUnchecked startActivityUnchecked中处理了关于Activity启动模式的处理,接着真正的resume我们的Activity 这里会先判断应用进程是否创建,创建了就进入 realStartActivityLocked ,没创建就会调用 ActivityManagerInternal.startProcess ①热启动realStartActivityLocked 接着看ActivityThread中接收并处理消息的handleMessage 前面realStartActivityLocked方法中通过addCallback,传入参数LaunchActivityItem。executeCallbacks方法中取出callbacks集合中的LaunchActivityItem,并调用其execute方法 handleLaunchActivity ②冷启动创建应用进程ActivityManagerInternal.startProcess ActivityManagerInternal的实现类是AMS中的LocalService,AMS通过Socket与Zygote通信,fork出App进程,app进程创建后,会执行ActivityThread的main方法(Android进程入口方法) 调用ActivityThread的attach [4]thread.bindApplication 这是一个binder通信的过程 ActivityThread内部的Handler接收到BIND_APPLICATION消息 回到上面attachApplicationLocked的mAtmInternal.attachApplication,调用ATMS的attachApplication 看到了似曾相识的realStartActivityLocked,后面流程和之前一样。Activity启动流程分析完毕。 总结 1)与Activity管理有关的类: ActivityRecord :历史栈中的一个条目,代表一个Activity TaskRecord :内部维护了一个ArrayList ,来保存ActivityRecord ActivityStack :内部维护了一个ArrayList,用来管理TaskRecord ActivityStackSupervisor :用来管理ActivityStack的 2)Activity启动流程