Activity的启动流程

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354