慕课网 android framework 笔记

 

二,android系统的启动流程

1, Android有哪些系统进程

2,系统进程如何启动

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

 

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

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

service zygote /system/bin/app_processservice servicemanager /system/bin/servicemanagerservice surfacelinger /system/bin/surfaceflingerservice 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 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查询所有当前已经安装的应用,把图标显示到桌面上,点击图标,就会启动应用的LauncherActivitymPm.queryIntentActivitiesAsUser

 

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

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

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

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

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

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

 

技巧点拨,面试技巧

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

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

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

 

更多相关文章

  1. Android启动画面
  2. Android(安卓)启动流程梳理
  3. Android(安卓)UI线程与子线程
  4. Android属性之build.prop,及property_get/property_set
  5. Android(安卓)更新UI的两个方法
  6. Android(安卓)Tcp服务器端
  7. Android(安卓)SDK and AVD Manage图标没找到
  8. 多线程例子 android camera capture
  9. Android学习笔记(7)————Android中的消息机制

随机推荐

  1. ContentProvider简单用法
  2. CyanogenMod 编译 Google Nexus S ("cres
  3. android常用view布局
  4. Android自定义视图控件
  5. android handler发送消息需要注意的地方
  6. Error:(1, 0) Cause: com/android/build/
  7. 学习android JNI的那些事儿--------4. Fi
  8. android动画学习之动画参数设置
  9. Android之项目推荐使用的第三方库,有助于
  10. Android富文本编辑器:XRichText