App启动流程:总体说明

概述:

“应用程序启动过程”其实说的就是“冷启动”过程。

App启动流程总体是由以下3部分组成

  • 为目标App启动做准备
  • 启动App进程
  • App进程内部操作

为目标App启动做准备(详细请戳 <<为目标App启动做准备>>)

这部分内容概括来说主要就是2件事:

  • “Launcher进程把待启动App的信息封装到Intent中,然后通过Binder把该信息发送给system_server进程中的AMS服务。
  • 然后AMS拿这些信息为启动App做一些前期的准备工作”。

这些工作内容细分如下:

  • 通过PMS.resolveIntent()根据提供的待启动Activity的Intent信息,从已安装的应用中解析出与该Activity相对应的ActivityInfo。
  • 检查传递来的参数,如果参数不正确,将会返回相应的err信息,用于提醒用户出现了什么错误。
    1. 如果,Intent获取的要启动的Activity组件的"ComponentName"信息为null的话(未通过Intent指定要跳转的Activity的确切的类名信息),则不会继续后续操作,并会返回此err。
    2. 如果,通过PMS找不到待启动Activity的详细信息(ActivityInfo),则不会继续后续操作,并会返回此err。
  • 与Activity栈相关操作
    1. 为待启动Activity组件新创建一个ActivityRecord。
    2. 缓存待启动ActivityRecord、调用者的ActivityRecord、Intent等信息。
    3. 初始化代启动Activity的lauchMode与launchFlags。
    4. 为代启动ActivityRcord创建或者选取一个可用的TaskRecord(因为启动的其它app的根Activity,所以会为该Activity创建一个新的TaskRecord)。
    5. 添加待启动ActivityRecord至“前台栈”的栈顶。
    6. 显示theme中设置的预览窗口。
    7. “暂停所有ActivityStack中处于RESUMED状态的Activity”,此时Launcher这个Activity也会被 Pause 掉。
    8. 激活“前台栈”中处于栈顶位置的待启动Activity。

启动App进程(详细请戳 <<启动App进程>>)

启动应用程序的进程主要分2个方面:

  • AMS向Zygote发起fork子进程的过程

    • AMS调用其内部的“startProcessLocked()”来开启启动app进程的入口。该方法主要做的是:组装发给zygote进城的用于启动子进程的参数列表(这些参数包括:uid,gid,entryPoint 参数等,entryPoint参数的值为ActivityThread的类全限定名。该参数用于fork子进程之后启动每个app进程的ActivityThread去做初始化操作。)
    • 通过层层调用最终会执行 ZygoteProcess.startViaZygote()
      1:首先,该方法首先会把AMS服务传过来的参数封装到一个argsForZygote参数列表中。
      2:其次,调用ZygoteProcess内部的openZygoteSocketIfNeeded()与Zygote进程建立Socket连接。
      3:最后,调用ZygoteProcess的zygoteSendArgsAndGetResult(),该方法主要做的事情是:将请求参数列表发送到zygote进程,并接收Zygote进程启动子进程的响应结果。
  • Zygote接收AMS的请求创建子进程过程

    • Zygote进程被init进程拉起后,会通过反射调用ZygotInit的main(),该方法主要做的事情是:
      1:初始化ZygoteServer并创建服务端Socket用于接收、执行其它进程向Zygote进程发起的请求
      2:启动SystemServer进程
      3:最后调用runSelectLoop()开始循环接收其它进程发起的请求
    • 如果检测到有请求发过来,runSlectLoop()中会把一次Socket封装成ZygoteConnection,而后执行其runOnce()方法。
    • 在runOnce()内部会调用Zygote.forkAndSpecialize():内部调用native方法进行实际的fork子进程操作。fork成功的话则子进程pid等于0,不为0则表示fork失败(fork()采用copy on write技术,这是linux创建进程的标准方法,调用一次,返回两次。)。
    • 如果pid为0,则表示当前代码执行在子进程,需要执行handleChildProc(),该方法主要做的是:
      1:关闭与Zygote进程的Socket连接。
      2:执行ZygoteInit.zygoteInit()。
      ZygoteInit.zygoteInit(),该方法主要执行"子进程"的运行时初始化操作(这些初始化包括:启动Binder线程池、创建VM、以及反射执行子进程ActivityThread线程等)。

App进程内部操作(详细请戳 <<App进程内部操作>>)

执行ActivityThread.attach(),进行“连接”操作。其中主要包括:

  • AMS.attachApplication():此时所在进程是fork之后的子进程。通过ActivityService.getService()获取AMS服务在本地进程的代理对象,然后通过Binder调用AMS的attachApplication()。

  • AMS.attachApplicationLocked():
    1:其内部会先调用ApplicationThread.bindApplication()初始化App进程的Application。具体的会向ActivityThread的Handler中发送一个BIND_APPLICATION消息。Handler在接收到发送的“BIND_APPLICATION消息”后去执行ActivityThread.handleBindApplication()。

    • ContextImpl.createAppContext():创建ContextImpl实例
    • 反射初始化Instrumentation实例,并赋值给 mInstrumentation。执行Instrumentation.init()进行初始化操作。
    • LoadApk.makeApplication():反射Application,并执行Application的attach(),onCreate()方法。

    2:等启动完App的Applicaiton后,AMS会调用ASS.attachApplicationLocked()通过App的ApplicationThread通知app初始化根Activity。具体操作如下:
    1:首先,调用ASS.attachApplicationLocked()。其内部会找到处于“前台栈”栈顶的待启动Activity。
    2:最后,调用ASS.realStartActivityLocked()通过Binder来通知App进程初始化待启动也就是App注册的根Activity。

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