【转】 Android是怎么样启动应用程序的,从点击启动图标到显示视图到底做了什么操作

转载自 https://juejin.im/post/5b0d0a0cf265da091f105858

本文阐述了用户点击启动图标后,Android 系统是怎么启动你的应用程序,将应用视图显示在移动设备上,Android 系统在背后做了很多操作,本文通过重点介绍将一些重要信息以及他们的顺序来阐述应用的启动过程。
首先说一下 Android 应用程序的两个特点

  1. 多入口,和只有一个 main 方法的应用程序不同,Android 应用程序有四大组件构成 ( Activity , Service ) ,每个组件都是一个入口,所以说 Android 应用是多入口的应用。
  2. 每个 Android 应用运行在一个 独立的 linux 进程拥有自己的 dalvik vm,并且分配唯一的的用户 ID。

那么什么时候会启动应用的进程呢,答案就是什么时候用到应用程序就启动,这种 ‘ 懒汉模式 ‘。

当用户或者其他应用程序用到了属于你的应用程序的组件,比如 ( Activity ,Service ) Android 就会为你的应用程序启动一个新的进程(你的应用进程不存在当前 Android 系统中时),启动的应用进程会伴随着整个 Android 系统,直到 Android 杀掉你应用进程(内存不足或者被用户清除)。

每个应用都有独立的进程,默认情况下,每个应用程序都运行在自己的进程,并且启动一个主线程工作。当你的应用程序 需要打开相册功能就会打开系统的相册应用,因为你的应用和相册应用都有自己独立的应用进程,通过启动相册的操作,在一个进程中启动另外一个进程,这适用于其他应用程序里面的每一个组件。

Android 开机过程
Android 开机的过程加载内核和 init 进程 然后 init 进程又会产生很多守护进程 比如 usb 进程 debug 调试进程 ,这些守护进程一般是处理底层硬件接口。
然后 init 进程又会启动一个 zygote 进程 ,zygote 进程他会创建一个原始 dalvik 虚拟机 然后继承系统资源,和 Android 应用程序框架,然后进入监听状态,随时准备复制一份,当系统请求 zygote 就会 fork出一份新的进程,这个进程就有了 dalvik 虚拟机和系统的资源了。

然后 init 进程还会启动系统服务进程 SystemServer,SystemServer 去创建系统服务类比如 ActivityManagerService (AMS)。再去启动 launcher 应用(桌面启动器)。

所以当在桌面点击 启动 logo 就会通过 binder接口 以ipc的形式,通知 ams 会发起一个startactivity 然后通过 packagemanager.resolveIntent 来获取 activity的信息,并且保存起来,下次就拿来用。
然后调用 geturipermissionlocked 判断有没有权限执行这个操作,然后 ams 检查 activity 在哪个应用栈列里面,然后再判断 activity 所在的 应用进程是否存在,如果 ams 检测到 activity 所在进程为空会去 通知 zygnote 去fork 一个进程,执行 activitythread 的 main 方法 实例化 looper 消息队列,调用 looper。loop去循环消息队列。,然后进程和 ams 绑定在一起,下次就不会创建该activty了。

启动应用程序可以分为三个步骤

  1. 创建一个进程
  2. 绑定应用程序
  3. 启动一个 Activity
163aee65e35936d8.png

创建一个进程

ams 会通过 startprocessLocked 方法向 zygote 请求一个新的进程,通过 socket 的方法 向 zygote 传递参数,zygote fork了一份 调用 zygoteInit.main 方法 ,然后实例化 Activitythread 对象 并返回进程的 id。

每一个进程都有一个主线程,主线程的有一个looper实例来处理消息队列里面的,在遍历里面的消息队列时,run 方法 会调用 looper.loop 方法。 activitythread 也会调用 looper.prepareLoop 和looper.loop 来启动消息循环。详细如图:


163aef7f73aef0d3.png

进程绑定应用程序

这一步的作用就是将进程绑定到应用程序上, ams 调用 bindApplicaiton,让线程发送一个 message 给消息队列,最后在 handler 的 handlemessage 方法调用 hanldebindapplicaiton 方法,接着调用 makeApplicaiton ,将应用程序的类加载到内存上。如图:


163aefd430ac7121.png

启动一个 Activity

上面两步为你创建了进程和加载资源类到进程的内存里面,这一步为了 ams 调用 realstartactiivtyLocked 来启动 activity ,然后调用 schedulelauncheractivity 方法 ,让 Activitythread 发送LAUNCH_ACTIVITY 的标识,然后在 handleMessage 方法调用 handlelaunchActivity 和 performLaunchActivity ,通过 newActivity 传入 classloader,classname 和 intent 来创建对应的 activity 最后调用 oncreate 加载视图方法 setcontentview。最后视图显示在手机上。 如图:


image

总结

当你启动一个 activity 的时候 ,你当前的进程通过 binder 接口 以 ipc 的方式 startactivity 请求 AMS , AMS 判断用户有没有权限请求这个actiivty 再根据应用栈来确定新 activity 的 task ,最后请求 zygote 创建 dalvik 虚拟机 以及加载系统资源类 ,来创建新的进程,调用新进程的 activitythread 类的 main 方法 创建 looper 调用 loop 方法来遍历消息队列。然后 zygote 返回新进程 pid 给 AMS 。 AMS 绑定这个进程到应用上,加载类到进程的内存上,最后调用 handlelaunchActivity 和 performlaunchactivity 启动这个 activity。最后执行 activity 的 oncreate 方法加载视图,执行 onstart 方法使视图可见。

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,059评论 25 707
  • Zygote是什么?有什么作用? Android系统底层基于Linux Kernel, 当Kernel启动过程会创...
    Mr槑阅读 2,806评论 4 18
  • 一直觉得自己耐性挺好的。只要时间允许,我不介意自己在等…… 一个周末,朋友约着出去逛街,逛街这事对我来说,可去可不...
    云上之人阅读 339评论 2 2
  • 曾记否,母亲怀胎十月,举步维艰,诞下了我。 又曾记否,儿时的朗朗书声,纯真的我。 而今的我,是流逝的时间与大千世界...
    灬苦行人辑首作揖乀阅读 287评论 0 1
  • 又跌倒了!这次很惨!原于贪婪,原于恐惧,原于自己干了自己干不了的事情!这么大的负债,谁也帮不了我!我象在雨天烂泥路...
    文荷鑫阅读 342评论 1 1