Android framework 系统服务的启动流程

慕课网 android framework 笔记

 

二,android系统的启动流程

1, Android有哪些系统进程

2,系统进程如何启动

3,进程启动后做了什么事情

 

android有哪些系统进程?可以看看init.rc

里面定义了很多service,就是要单独启动的系统服务进程

service zygote /system/bin/app_process
service servicemanager /system/bin/servicemanager
service surfacelinger /system/bin/surfaceflinger
service media /system/bin/mediaserver

还有一个非常关键的系统服务:System server,,它不在init.rc,因为它是zygote创建的,不是init进程创建的,

所以搞定zygote和system server的启动流程就好了

 

zygote怎么启动?

init进程fork出zyogte进程

启动虚拟机,注册jni函数,为进入java层做准备

预加载系统资源,如系统主题资源,类等

启动system server,非常重要,里面跑了很多系统服务

进入socket Loop,不断接受socket消息并处理

 

zygote工作流程:

启动的最后,进入了socket loop循环,有消息进入runOnce()函数,如上

boolean runOnce(){
    String[] args = readArgumentList(); //读取参数列表
    int pid = Zygote.fotkAndSpecialize(); //根据参数启动子进程
    
    if(pid == 0){
        //in child
        handleChildProc(args, ...); 
        //在子进程里面干活,其实执行的就是java类得main函数(入口函数),java类名来自上面读取的参数列表。
        //参数列表是AMS跨进程发过来的,类名就是ActivityThread.main(),
        //也就是说,应用程序进程执行后会马上执行ActivityThread.main()函数
        return true;
    }
}

 

system server如何启动

private static boolean startSystemServer(...){
    String args[] = {
        ...
        "com.android.servver.SystemServer",
    }
    int pid = Zygote.forkSystemServer(...); //创建system server进程,zygote fork出来
    if(pid == 0){
        handleSystemServerProcess(parsedArgs); //子进程,走进system server启动的具体逻辑了
    }
    return true;
}

void handleSystemServerProcess(Arguments parsedArgs){
    RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,paresdAegs.remainingArgs,...);
}

//初始化分三步
void zygoteInit(String[] argv, ...){
    commonInit();
    nativeZygoteInit(); //这步比较重要
    applicationInit(argv,...);
}

//nativeZygoteInit(),这里启动了binder机制,binder线程,因为system server里很多系统服务需要和其他进程通信
//如何应用进程通讯,或者和service manager进程通信
virtual void onZygoteInit(){
    sp<ProcessState> proc = ProcessState::self();
    proc->startThreadPool();
}

3,applicationInit
//调用java类的入口函数,就是system server的java类
void applicationInit(){
    invokeStaticMain(args,...);
}

//system servier的类的main函数
public static void main(String[] args){
    new SystemServer().run();  //new了一个SystemServer对象,执行了它的run函数
}

private void run(){
    Looper.prepareMainLooper(); //为主线程创建Looper
    
    System.loadLibrary("android_servers"); //加载共享库,就是system server里的系统服务的native 层的代码,都在共享库
    createSystemContext(); //创建系统上下文,system server可以看成是应用进程,因为它也有context,application,Activity thread
//系统服务分3批次,分别启动    
    startBootstrapServices();
    startCoreServices();
    startOtherServices();
    
    //不管这个loop是不是真的在处理消息,但这个主线程不可以退出,主线程退出进程就退出了
    Looper.loop();
}

 

看两个问题:

系统服务如何启动?

怎么解决系统服务之间互相依赖?

 

系统服务怎么启动?

系统服务怎么发布,让应用程序可见?

系统服务跑在什么线程?

 

1)系统服务怎么发布?

//就是系统服务把binder注册到ServiceManager里面
void publishBinderService(String name, IBinder service){
    publishBinderService(name, service, false);
}

void publishBinderService(String name, IBinder service,...){
    ServiceManager.addService(name, service, allowlsolated);
}

 

2)系统服务跑在什么进程?

1))是主线程吗?没有哪个系统服务用了主线程,主线程什么都没干。

2))工作线程?两种情况

有的服务有自己的工作线程:AMS PMS 还有Package manager service //08:03,PMS还是WMS?

还有大家共用的工作线程:DisplayThread, FgTHread, IoThread, UiThread。

DisplayThread是显示用的

FgThread是前台任务

IoThread是Io任务

UiThread是Ui显示的,UiThread并不是主线程,而是一个子线程,所以说明UI的刷新不必一定在主线程,子线程也行

3))跑在binder线程?

一定的,因为应用跨进程调过来肯定先在binder线程里面

 

作业:

1),为什么系统服务不都跑在binder线程,

2),为什么系统服务不都跑在自己私有的工作线程?

3),跑在binder线程和跑在工作线程,如何取舍?

答案:

1)binder形成是大家共享的,如果系统负载重,binder线程池忙碌,可能影响系统服务响应的实时性,而且如果任务太耗时,长时间占用binder线程也不好。

2)不可能每个服务都启动工作现场,一共上百个系统服务,线程开太多会内存溢出的,太多线程之间切换对性能不利。

3)如果对实时性要求不高,处理不好使的任务可以放在binder线程。

另外启动工作线程可以避免同步问题,因为AP挂检查调用过来是在binder线程池,通过切到工作线程就可以让binder调用序列化,不用到处上锁。

 

2,怎么解决系统服务启动的互相依赖

服务A依赖服务B,B依赖C

像system server里,系统服务有7 80个,解决复杂的依赖关系不容易,

1)分批次启动,要启动的service分成三批次,

基础的先启动:AMS PMS PKMS,很多service都依赖于他们所以要先启动

2)分阶段启动,通知已启动的service到了什么阶段,哪些资源可以用了,这些service就可以做这个阶段可以做的初始化了。

 

桌面的启动

AMS服务就绪时会调用systemReady函数,里面会启动桌面

public void systemReady(final Runnable goingCallback){
    ...
    startHomeActivityLocked(mCurrentUserId, "systemReady");
    ...
}

桌面可以看成单独的系统级的应用,这里只启动了桌面的Activity,Activity的onCreate里面会启动LoaderTask

mLoaderTask = new LoaderTask(mApp.getContext(), loadFlags);
//loaderTask会想packageManagerService查询所有当前已经安装的应用,把图标显示到桌面上,点击图标,就会启动应用的LauncherActivity
mPm.queryIntentActivitiesAsUser

 

回到题目,说说Android系统的启动流程:

简单的说肯定不行:启动zygote , systemserver, 桌面

也不用说的太细,因为涉及太多,一天也说不完,流程说清,主要围绕zygote,systemserver展开,

1)zygote如何启动,启动后做什么事情,最后怎么进入socker looper循环等待创建应用进程的,

2)system server怎么启动,做什么事情,这个进程做什么用的,

3)系统服务怎么启动的,怎么解决相互依赖,怎么发布到service manager的,桌面怎么启动的

 

技巧点拨,面试技巧

1) 条理清晰,what how why,对于复杂的问题,如果没有一条线穿起来,会很没有条理,

2) 结论 + 细节,是什么后有为什么,证明思考过,有自己的想法和思路

3) 有技巧的转移话题到自己熟悉的领域

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值