惊呆了!女儿拿着小天才电话手表,问我Android启动流程!

首先,new一个女儿,

var mDdaughter = new 女儿(“6岁”,“漂亮可爱”,“健康乖巧”,“最喜欢玩小天才电话手表和她的爸爸”)

好了,女儿有了,有一天,女儿问我:

“爸爸爸爸,你说我玩的这个小天才电话手表怎么这么厉害,随便点一下这个小图片,这个应用就冒出来了,就可以听儿歌了。好神奇啊。”

我心里一惊:

小天才电话手表的系统就是Android,所以这不就是。。面试官常考的应用启动流程嘛!女儿也要来面试我了吗!好了,既然女儿问了,那就答吧。但是,对付这个小小的0经验面试官,我该咋说呢?

解答小小面试官

女儿,你可以把手表里面想象成一个幼儿园,里面有一个老师,一个班长,一个班干部,以及一大堆小朋友。

一个老师:Z老师(Zygote进程)

一个班长:小A(ActivityManagerService)

一个班干部:小L(Launcher桌面应用)

一大堆小朋友:所有应用,包括音乐小朋友,聊天小朋友,日历小朋友等等。

应用启动过程就像一个小朋友被叫醒一样,开机之后呢,Z老师会依次叫醒班长和班干部(SystemServer#ActivityManagerService,Launcher),小L醒了之后就会去了解手表里有哪些小朋友,长什么样(icon,name),家庭信息(包名,androidmanifest)等等,然后一个个把小朋友的照片(icon)贴到自己的身上。比如有音乐小朋友,聊天小朋友,日历小朋友,其实也就是你手表上这个桌面啦。

在这里插入图片描述

这时候你要点开一个音乐小朋友呢(startActivity),小L就会通知班长小A(Binder),小A知道了之后,让小L自己休息下(Paused),然后就去找Z老师了。Z老师就负责叫音乐小朋友起床了(fork进程,启动ActivityThread),音乐小朋友起来后就又找小A带她去洗脸刷牙(启动ApplicationThread,Activity),都弄完了就可以进行各种表演了,唱歌啊,跳舞啊。

女儿似懂非懂的给我点了一个赞,爸爸你真棒。

十五年后

mDdaughter.grow(15)
mDdaughter.study(“Android”)
复制代码

过了十五年,女儿已经21岁了,正在学习Android,考虑要不要女从父业。

这天,她一脸疑惑的来找我: “爸,这个app启动到底是怎么个流程啊,我看了好久还是不大明白,要不你再跟我详细讲一遍吧?” “好嘞,别担心,我这次详细跟你说说”

解答Android程序媛

还记得我小时候跟你说过的故事吗,Android系统就像一个幼儿园,有一个大朋友叫Launcher,身上会贴很多其他小朋友的名片。这个Launcher就是我们的桌面了,它通过PackageManagerService获知了系统里所有应用的信息,并展示了出来,当然它本身也是一个应用。

通过点击一个应用图标,也就是触发了点击事件,最后会执行到startActivity方法。这里也就和启动Activity步骤重合上了。

那么这个startActivity干了啥?是怎么通过重重关卡唤醒这个应用的?

首先,介绍下系统中那些重要的成员,他们在app启动流程中都担任了重要的角色.

系统成员介绍

init进程,Android系统启动后,Zygote并不是第一个进程,而是linux的根进程init进程,然后init进程才会启动Zygote进程。

Zygote进程,所有android进程的父进程,当然也包括SystemServer进程

SystemServer进程,正如名字一样,系统服务进程,负责系统中大大小小的事物,为此也是启动了三员大将(ActivityManagerService,PackageManagerService,WindowManagerService)以及binder线程池。

ActivityManagerService,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,对于一些进程的启动,都会通过Binder通信机制传递给AMS,再处理给Zygote。

PackageManagerService,主要负责应用包的一些操作,比如安装,卸载,解析AndroidManifest.xml,扫描文件信息等等。

WindowManagerService,主要负责窗口相关的一些服务,比如窗口的启动,添加,删除等。

Launcher,桌面应用,也是属于应用,也有自己的Activity,一开机就会默认启动,通过设置Intent.CATEGORY_HOME的Category隐式启动。

搞清楚这些成员,就跟随我一起看看怎么过五关斩六将,最终启动了一个App。

第一关:跨进程通信,告诉系统我的需求

首先,要告诉系统,我Launcher要启动一个应用了,调用Activity.startActivityForResult方法,最终会转到mInstrumentation.execStartActivity方法。 由于Launcher自己处在一个单独的进程,所以它需要跨进程告诉系统服务我要启动App的需求。 找到要通知的Service,名叫ActivityTaskManagerService,然后使用AIDL,通过Binder与他进行通信。

这里的简单说下ActivityTaskManagerService(简称ATMS)。原来这些通信工作都是属于ActivityManagerService,现在分了一部分工作给到ATMS,主要包括四大组件的调度工作。也是由SystemServer进程直接启动的,相关源码可见ActivityManagerService.Lifecycle.startService方法,感兴趣朋友可以自己看看。

接着说跨进程通信,相关代码如下:

//Instrumentation.java
int result = ActivityTaskManager.getService()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);


//ActivityTaskManager.java            
public static IActivityTaskManager getService() {
    return IActivityTaskManagerSingleton.get();
}
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
        new Singleton<IActivityTaskManager>() {
            @Override
            protected IActivityTaskManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                return IActivityTaskManager.Stub.asInterface(b);
            }
        };



//ActivityTaskManagerService.java
public class ActivityTaskManagerService extends IActivityTaskManager.Stub

public static final class Lifecycle extends SystemService {
    private final ActivityTaskManagerService mService;

    public Lifecycle(Context context) {
        super(context);
        mService = new ActivityTaskManagerServ
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值