Activity的启动流程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Activity的启动流程相关的知识,希望对你有一定的参考价值。

参考技术A 公众号

面试官:说说 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的启动流程的主要内容,如果未能解决你的问题,请参考以下文章

深入理解Activity启动流程–Activity Task的调度算法

Activity的启动流程

Activity的启动流程

深入理解Activity启动流程–Activity启动相关类的类图

Activity启动流程笔记

Android 启动过程Android 应用启动流程 | Activity 启动流程