Applicationthread是Activitythread和AMS通信的桥梁
-
Activity的启动过程,可以从Context的startActivity说起,其实是ContextImpl的startActivity。
-
内部通过Instrumentation尝试启动Activity,他会调用ams的startActivity方法,这是一个跨进程的过程。
-
当ams校验完Acitivity的合法性后,会通过ApplicationThread回调到我们的进程,也是一次跨进程过程。
-
ApplicationThread就是一个binder,回调逻辑在binder线程池中完成,所以通过Handler H将其切换到ui线程,第一个消息是LAUNCH_ACTIVITY,对应handleLaunchActivity,在此方法完成Activity的创建和启动。
-
performLaunchActivity完成Activity对象的创建和启动,ActivityThread通过handleResumeActivity来调用被启动Activity的onResume。
performLaunchActivity完成了这些操作:
- 从ActivityClientRecord中获取待启动的Activity组件信息
- 通过Instrumentation 的newActivity方法,使用类加载起创建Activity对象
- 通过LoadedApk的makeApplication尝试创建Application对象。
- 调用 createBaseContextForActivity 方法去创建 ContextImpl,调用 Activity.attach ( contextImpl , application) 这个方法就把 Activity 和 Application 以及 ContextImpl 关联起来
- 调用 Activity.onCreate 生命周期回调
面试官:说说 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
ActivityThread
1.从本质来看,它不是一个线程,而是一个Java类;
2.需要在主线程的方法中被运行;
3.运行时,首先调用main方法,其中也会调用:OnAttatch,loop方法;
4.AMS--->ActivityManagerService;
5.ActivityManagerService;
5.一个线程中,只有一个Looper对象;
ApplicationThread
-
ApplicationThread 继承自ApplicationThreadNative 继承自Binder
ApplicationThread 与ActivityManagerServer进行通信,以控制Activity的声明周期方法,通信方式通过Binder进行简化,具体的通信方法在ApplicationThread内部自己实现 -
ApplicationThread 在ActivityThread的类成员变量中被初始化
ActivityClientRecord && ActivityRecord
- ActivityClientRecord时Activity信息描述的类
ActivityInfo 也是对Activity信息的描述,如主题,权限,启动方式,任务栈等
- ActivityRecord是ActivityManagerServer中Activity的记录信息,Activity记录体的类,对应的在ActivityThread中就是ActivityClientRecord类
ActivityRecord、TaskRecord和ActivityStack
– ActivityRecord:可以从它的类命名知道,这个记录Activity信息的类,主要记录一个Activity的所有信息。一个ActivityRecord只能对应一个Activity,但是一个Activity在系统中可以存在多份实例,所以一个Activity可以对应多个ActivityRecord记录
– TaskRecord:TaskRecord由一个或者多个ActivityRecord组成,TaskRecord就是常说的任务栈,用来记录一个task里面的调用Activity的相关信息
– ActivityStack:是用来管理TaskRecord的,一个ActivityStack会包含多个TaskRecord
Instrumentation作用
1、Application的创建。
2、生命周期的管理。
3、启动Activity。
ActivityManagerNative
ActivityManagerNative是远程代理对象。通过ActivityManagerNative来操纵ActivityManagerService进行通信。客户端需要和ActivityManagerService进行通信,但是它们在不同的进程中,需要进行跨进程间进行通信,底层是用Binder实现。
H
H类(Handler类的子类)会处理大量的ActivityManagerServer跨进程发送过来的消息,如启动Activity,暂停Activity等等
oncreate
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方法
resume
mH当中的handleResumeActivity方法处理ActivityManagerService返送的消息
Activity的performResume()方法通过mInstrumentation.callActivityOnResume(this)方法调用到Activity的onResume()方法
WindowManager 接口,继承与ViewManager接口
ViewManager接口中的方法有3个:
- addView
- updateViewLayout
- removeView
调用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
destory实际并没有直接销毁掉activity (8.1源码)
通过performDestroyActivity()执行相应的生命周期方法performPauseActivityIfNeeded()、callActivityOnStop()、callActivityOnDestroy和移除它的IBinder
通过WindowManager的实现类WindowManagerImpl调用removeViewImmediate(),拿到activity的实际控制类ViewRootImpl对象将他的父窗口(父布局)的指定分派为null
将activity的content清理
网友评论