按下应用图标,追寻开启应用源码之旅

今天跟同事讨论应用启动的问题,关于应用如何启动的 ,我想追踪下源码,但是却不知道从什么地方开始,于是我想就从按下应用图标开始到界面启动吧,于是坐下打开source insight,其实,最近总结了一点看源码的诀窍,就是你想要知道什么,你就从哪个地方开始看源码,直到源码实现了你所要知道的东西,其实源码为什么看起来这么费劲,实际上运用了大量的设计模式导致容易走入死胡同。那么怎么绕开这个呢?多看,多想。好了不废话,下面走入源码世界。

在解析源码前,我们需要知道几个东西,1、init进程 2、zygote进程,3、systemserve。为什么会跟这几个相关联呢?别慌,下面就一一来作答,首先我们需要知道的是init进程,init进程是系统的第一个进程,我们要知道,系统启动的顺序,1、首先会加载引导程序,2然后启动Linux内核,3、最后启动init进程,那么init进程到底做了什么呢?其实init进程 主要创建和挂载启动所需的文件目录,其次初始化和启动服务(上述的systemserve)3、解析init.rc文件并启动zygote进程。通俗来讲init进程就是系统启动的入口。那么zygote进程是干嘛的呢?我们来看看源码。

首先获取到一个zygoteserver对象,那么这个对象有什么用呢?继续看下面

可以看到通过一个socket注册了一个与服务端连接的socket,那么为什么需要这个socket呢?我们要知道,在上面说了,init进程和zygote进程是在系统内部的,如果我们应用要启动需要zygote进程来加载资源和启动相关服务,这个时候就需要与服务端建立连接,所以需要注册一个serversocket.

回到zygoteinit中去,除了注册serversocket,还做了什么呢?

预加载资源,

然后启动systemserver和等待activitymanagerservice的请求,好了这个时候前期工作已经完毕,记住一点这个时候的工作室在jni层完成的,

接下来看看launcher的启动,launcher的启动是由activitymanagerservice来完成,刚刚上面说了,在runselectloop这个方法中实际上就是systemservice等待ams的请求,那么请求什么呢?实际上请求启动创建应用进程的,如果当前进程存在则启动,不存在则创建,怎么创建呢,其实是通过zygote的fork复制的,那为什么要复制呢?因为复制可以直接将需要的资源和虚拟机一起clone一份,减少资源加载和虚拟机的创建,接下来看ams的源码是怎么启动launcher的,

首先,我们启动launcher之前肯定需要做几件事情,1,创建一个任务栈,为什么要这个,因为我们的activty需要放入栈中,因为栈中的数据我们可以通过压栈和弹栈操作,可以设置activty在栈中的位置,这个可以控制activty的启动模式,而且系统界面的调用也需要这个,比如我们当前应用需要调用系统的相册,电话,拍照等界面,这个时候将系统界面压栈,处于用户可视范围,调用完弹栈即可。回归上述,如何创建一个任务栈呢?接下来看源码

创建完之后,我们需要让启动的home栈处于resume状态,因为启动的时候,需要将将要启动的activty置于这个栈的顶端。接下就是通过ams来启动launcher,那么启动之前我们需要做什么呢?可以对比下activty,我们需要知道当前launcher的intent的信息,

是不是感觉跟mainfest.xml文件中mainactivity的设置很像呢?没错,这个就是设置launcher作为入口的。以上的启动条件全部准备好了,现在只需把launcher放入homestack中就可以了,后续就会通过startActivityLocked方法启动launcher了。

综上,我们来总结下流程:

1、首先会开启一个init进程,因为这个进程是系统的第一个进程,所以这个进程需要创建和挂载启动所需的文件资源,然后启动必要的服务,例如BootLoader引导服务。启动zygote进程。

2、zygote进程会创建一个server端的socket,然后预加载资源,启动systemserver,等待AMS发送的请求,

3、AMS会请求启动一个应用进程,同时AMS会创建一个任务栈,

4、确保任务栈处于resume状态

5、然后设置启动launcher需要的intent的信息作为启动的信息携带者

6、将launcher放入创建的任务栈中,调用startActivityLocked启动。

此时从系统到launcher启动已经完成了,但是此时页面并没有启动,activity这个时候还没有启动,接下来我们看看activity怎么启动的。

首先我们启动activty是通过startactivty来启动activty的,我们直接进入startactivty源码内部去看看。

startactivty直接调用了startActivityForResult方法,我们继续探寻startActivityForResult的源码,看看这个方法内部做了什么


mInstrumentation是用来监控应用程序和系统的交互

在这里,创建了一个AMS的代理类来执行Ams的一些操作,这里使用了代理模式,使得服务端和应用端能够执行相应的方法。此时执行程序的操作就交给AMS来完成了,这段代码重要的功能便是将调用者转给AMS,接下来我们区看AMS的startactivty方法。

这段代码直接返回AMS的startActivityAsUser方法,那么这个方法是干什么的呢/我们去内部看看,

这个方法最重要的一点就是根据userID来确定启动的权限。

检查权限后创建intent,并根据intent的相关信息找到指定的需要启动的activty,此时找到对应的activty需要将activity放入栈中,而根据上述来说,activityStack是管理栈的,

,栈创建完毕,直接调用栈的resumeTopActivityUncheckedLocked方法,那么这个方法是干嘛的呢?

确保栈顶的activty是处于resume状态,这样能够即将能够展示在界面。这个时候我们进入方法resumeTopActivityinnerLocked内部可以看到调用ActivtyThread的scheduleLaunchActivity方法,那么此时,启动来到ActivtyThread中,ActivtyThread的实现类是applicationThread,这个类是AMS所在进程与应用进程的通信桥梁,这个ActivtyThread是管理activity的线程管理类。在ActivtyThread中会调用scheduleLanucgActivty方法,这个就是发送启动消息的。那么我们来看看发送消息。

发送消息后肯定要处理消息,接下来看看怎么去处理这个消息的。

终于看到了执行启动activty的方法了,就是它,这个performLaunchActivity,到这里activty就启动了,那么在启动之前还会初始化一些信息,看看初始化哪些必要信息呢?

看上述红箭头指示,

1,获取一个activityInfo,内部包含了启动的activty的所有信息,

2、创建context上下文对象

3、创建activty的对象,

4、创建一个application

5、初始化一个activty,将上述获取的参数传入activty中


调用了activty的oncreate的生命周期方法,到此时,整个activity才真正的启动了。

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

推荐阅读更多精彩内容