美文网首页
Activity的启动流程

Activity的启动流程

作者: 卡路fly | 来源:发表于2020-05-16 15:24 被阅读0次

Applicationthread是Activitythread和AMS通信的桥梁

  1. Activity的启动过程,可以从Context的startActivity说起,其实是ContextImpl的startActivity。

  2. 内部通过Instrumentation尝试启动Activity,他会调用ams的startActivity方法,这是一个跨进程的过程。

  3. 当ams校验完Acitivity的合法性后,会通过ApplicationThread回调到我们的进程,也是一次跨进程过程。

  4. ApplicationThread就是一个binder,回调逻辑在binder线程池中完成,所以通过Handler H将其切换到ui线程,第一个消息是LAUNCH_ACTIVITY,对应handleLaunchActivity,在此方法完成Activity的创建和启动。

  5. performLaunchActivity完成Activity对象的创建和启动,ActivityThread通过handleResumeActivity来调用被启动Activity的onResume。

performLaunchActivity完成了这些操作:

  1. 从ActivityClientRecord中获取待启动的Activity组件信息
  2. 通过Instrumentation 的newActivity方法,使用类加载起创建Activity对象
  3. 通过LoadedApk的makeApplication尝试创建Application对象。
  4. 调用 createBaseContextForActivity 方法去创建 ContextImpl,调用 Activity.attach ( contextImpl , application) 这个方法就把 Activity 和 Application 以及 ContextImpl 关联起来
  5. 调用 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

  1. ApplicationThread 继承自ApplicationThreadNative 继承自Binder
    ApplicationThread 与ActivityManagerServer进行通信,以控制Activity的声明周期方法,通信方式通过Binder进行简化,具体的通信方法在ApplicationThread内部自己实现

  2. ApplicationThread 在ActivityThread的类成员变量中被初始化

ActivityClientRecord && ActivityRecord

  1. ActivityClientRecord时Activity信息描述的类

ActivityInfo 也是对Activity信息的描述,如主题,权限,启动方式,任务栈等

  1. 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清理

相关文章

网友评论

      本文标题:Activity的启动流程

      本文链接:https://www.haomeiwen.com/subject/wzxfohtx.html