Activity 启动过程

应用进程

启动,调用 ContextImpl 的 startActivity(); 最终调用的 startActivityForResult(); 方法

startActivityForResult 中调用 Instrumentation 的 execStartActivity();

execStartActivity 中调用 ActivityManagerNative.getDefault().startActivity();

ActivityManagerNative.getDefault();方法得到的是 IActivityManager ,该类继承了 IInterface 接口,ActivityManagerNative 继承了 Binder 并实现了 IActivityManager 接口,ActivityManagerService 继承了 ActivityManagerNative,也是一个 Binder,是IActivityManager 的具体实现类。

ActivityManagerNative.getDefault 方法中通过 Binder 机制得到 ActivityManagerNative 实现类 ActivityManagerService 对象的代理类 ActivityManagerProxy 的对象,在 ActivityManagerNative 中以单例的形式提供,ActivityManagerNative.getDefault() 得到的是 ActivityManagerProxy 对象,通过该对象的 startActivity 方法会远程调用系统进程 ActivityManagerService 对象的 startActivity 方法。

Instrumentation 的 execStartActivity 方法中接着调用 checkStartActivityResult() 由 AMS.startActivity 方法的返回值判断 Activity 是否注册,未注册抛出异常。

IActivityManager --> ActivityManagerNative --> ActivityManagerService(实现类) (ActivityManagerProxy 客户端中的代理类)

系统进程

ActivityManagerService 的 startActivity(); 方法中调用 ActivityStackSupervisor.java 和 ActivityStack.java 两个类中的方法,最终在 ActivityStackSupervisor 类的 realStartActivityLocked 方法中调用 app.thread.scheduleLaunchActivity(); 方法。

app.thread 类型为 IApplicationThread,是一个接口,继承了 IInterface 接口,其中定义了大量启动、停止Activity 和 服务接口,即 IApplicationThread 的实现类对象完成了启动及停止 Activity 和 Service 的功能。

ApplicationThreadNative 是抽象类, 继承了Binder 并实现了 IApplicationThread 接口,即为一个 Binder,ApplicationThread 为 其具体实现类,也为一个 Binder, ApplicationThread 是 ActivityThread 中的内部类。在启动 Activity 时从客户端通过进程间通信将 ActivityThread 的对象传递到了系统进程,系统进程通过 IPC 得到了 ActivityThread 的代理类 ActivityThreadProxy 的对象.

app.thread 为 ActivityThreadProxy 类的对象,通过调用 ActivityThreadProxy 对象的方法会经过进程间通信调用 ActivityThreadNative 实现类对象中的方法,也就是调用其实现类 ApplicationThread 对象中的方法,所以系统进程中调用 app.thread 的 startActivity 方法时会在应用进程中调用 ApplicationThread 类对象的 startActivity 方法。

应用进程

通过 ApplicationThead 的 scheduleLaunchActivity(); 该方法中通过ActivityThread 中的 Handler 发送 Message ,将执行线程从 Binder 线程切换到主线程, Handler 中调用 ActivityThread 的 handleLaunchActivity() 方法并从中调用 performLaunchActivity() 完成Activity对象的创建及启动,handleLaunchActivity 中再调用 handleResumeActivity 方法调用被启动Activity 的 onResume() 方法

应用进程中 Activity 的创建与启动

performLaunchActivity() 方法中,

  • 第一步,从 ActivityClientRecord 中获取待启动的 Activity 的组件信息 ActivityInfo

  • 第二步,通过 Instrumentation 的 newActivity() 方法使用类加载器创建 Activity 对象
    Classloader.loadClass(String className).newInstance();

  • 第三步,通过 LoadeApk 类的 makeApplication 方法中 通过 Instrumentation 的 newApplication 方法创建 Application 对象,同样使用类加载器创建类对象,在创建 ContextImpl 对象,再将该 ContextImpl 对象与 Application 对象绑定并调用其 onCreate 方法。如果 Application 已经创建过则不会再次创建,一个应用只能有一个 Application 对象。

    • 通过 ContextImpl 的 createAppContext() 方法,创建 Application 的 ContextImpl 对象 appContext
    • ContextImpl创建之后,调用 appContext.setOuterContext(app) 方法将 ContextImpl 与 Application 绑定并完成数据初始化
    • 接着通过 Instrumentation 的 callApplicationOnCreate 方法调用 Application 的 onCreate 方法完成 Application 的启动。
  • 第四步,通过 ContextImpl 的 createActivityContext 创建 Activity 的 ContextImpl 对象,并通过 Activity 的 attach 方法与 ContextImpl 绑定并完成一些重要数据的初始化。attach 对象中,Activity 还会完成 Window 的创建并建立自己和 Window 的关联,这样当 Window 接收到外部输入事件后就可以将事件传递给 Activity。

  • 第五步,通过 Instrumentation 的 callActivityOnCreate 方法调用 Activity 的 onCreate 方法。完成启动。

Activity启动过程中的进程变化

ActivityThread 应用进程,在组件激活的过程中 ActivityThread 中的 ApplicationThread 实例对象会传递到 AMS 进程,AMS 进程会得到其代理对象,通过 ApplicationThread 代理对象的方法可以通过 IPC 调用应用进程的方法
当前应用进程主线程 --> AMS 系统进程 --> 通过 app.thread 切换到主进程并通过的 Handler 转移到应用进程主线程。

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

推荐阅读更多精彩内容