博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android源码(一)Android系统启动
阅读量:5747 次
发布时间:2019-06-18

本文共 7861 字,大约阅读时间需要 26 分钟。

一、整体流程

init进程 –> Zygote进程 –> SystemServer进程 –>Launcher启动

  • init进程:linux的根进程,android系统是基于linux系统的,因此可以算作是整个android操作系统的第一个进程;
  • Zygote进程:android系统的根进程,主要作用:可以作用Zygote进程fork出SystemServer进程和各种应用进程;
  • SystemService进程:主要是在这个进程中启动系统的各项服务,比如ActivityManagerService,PackageManagerService,WindowManagerService服务等等;
  • Launcher:作为系统桌面应用,用来显示应用列表,用户可以通过点击应用的icon启动某个应用

二、init进程

1、启动时机:

在Linux内核完成系统设置后,会再系统文件中寻找init.rc文件,并启动init进程。

2、主要作用:
  • 创建并挂载文件目录
  • 初始化和启动属性服务
  • 解析init.rc配置文件并启动zygote进程

三、Zygote进程

1、通过JNI调用到Java层的ZygoteInit中main方法
#ZygoteInitpublic static void main(String argv[]) {    ......    try {        ......        if (startSystemServer) {            //启动SystemService进程            startSystemServer(abiList, socketName, zygoteServer);        }        (1)        zygoteServer.runSelectLoop(abiList);        zygoteServer.closeServerSocket();    } catch (Zygote.MethodAndArgsCaller caller) {        caller.run();    } catch (Throwable ex) {        Log.e(TAG, "System zygote died with exception", ex);        zygoteServer.closeServerSocket();        throw ex;    }}复制代码

(1)创建了一个Socket,并通过runSelectLoop函数等待ActivityManagerService的请求来创建新的应用程序进程。

问题:ActivityManagerService什么时候创建?ActivityManagerService什么时候请求?

2、主要作用:
  • 创建Java虚拟机并为虚拟机注册JNI方法
  • 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。
  • 初始化Zygote中的各种类,资源文件,OpenGL,类库等等;
  • 创建一个Server端的Socket
  • fork出SystemServer进程
  • 通过registerZygoteSocket函数创建服务端Socket,并通过runSelectLoop函数等待ActivityManagerService的请求来创建新的应用程序进程。

四、SystemServer进程

1、启动Binder线程池
#ZygoteInitprivate static void handleSystemServerProcess(        ZygoteConnection.Arguments parsedArgs)        throws Zygote.MethodAndArgsCaller {        ......        ClassLoader cl = null;        if (systemServerClasspath != null) {            //创建PathClassLoader            cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);            Thread.currentThread().setContextClassLoader(cl);        }        //调用zygoteInit方法        ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);    }    /* should never reach here */}public static final void zygoteInit(int targetSdkVersion, String[] argv,        ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {    if (RuntimeInit.DEBUG) {        Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");    }    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");    RuntimeInit.redirectLogStreams();    RuntimeInit.commonInit();    //启动Binder线程池    ZygoteInit.nativeZygoteInit();    //调用SystemService的main方法    RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);}#app_main.cppvirtual void onZygoteInit()    {        sp
proc = ProcessState::self(); ALOGV("App process: starting thread pool.\n"); //启动了Binder线程池 proc->startThreadPool();//1 }复制代码

问题:Binder线程池原理

2、启动系统服务

在SystemServer的main方法中调用run方法

#SystemServerprivate void run() {    try {        (1)        mSystemServiceManager = new SystemServiceManager(mSystemContext);        mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);        // Prepare the thread pool for init tasks that can be parallelized        SystemServerInitThreadPool.get();    } finally {        traceEnd();  // InitBeforeStartServices    }    // Start services.    try {        traceBeginAndSlog("StartServices");        (2)        startBootstrapServices();        (3)        startCoreServices();        (4)        startOtherServices();        SystemServerInitThreadPool.shutdown();    } catch (Throwable ex) {        Slog.e("System", "******************************************");        Slog.e("System", "************ Failure starting system services", ex);        throw ex;    } finally {        traceEnd();    }}复制代码

(1)创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理

(2)startBootstrapServices函数中用SystemServiceManager启动了ActivityManagerService、PowerManagerService、PackageManagerService等服务
(3)startCoreServices启动了BatteryService、UsageStatsService和WebViewUpdateService等服务
(4)startOtherServices启动了CameraService、AlarmManagerService、VrManagerService等服务

比较重要的服务例如:

  • ActivityManagerService:四大组件启动、切换等
  • PackageManagerService:apk安装、解析、删除等
  • CameraService:摄像头相关服务
  • AlarmManagerService:定时管理服务
  • WindowManagerService:窗口管理服务
  • NotificationManagerService:通知管理服务
  • InputManagerService:输入管理服务

系统服务启动:

#例如BatteryServicemSystemServiceManager.startService(BatteryService.class);#SystemServiceManager   private final ArrayList
mServices = new ArrayList
();public void startService(@NonNull final SystemService service) { //将某个系统服务添加到mServices中,完成了某系统服务注册工作 mServices.add(service); // Start it. long time = System.currentTimeMillis(); try { //启动Service service.onStart(); } catch (RuntimeException ex) { throw new RuntimeException("Failed to start service " + service.getClass().getName() + ": onStart threw an exception", ex); } warnIfTooLong(System.currentTimeMillis() - time, service, "onStart");}复制代码

系统服务获取:

  • 创建系统服务,并将系统服务注册到ServerManager中,ServerManager用来管理服务,用于Binder通信。
  • 注册到ServerManager中时会指定Service的名字,其后其他进程可以通过这个名字来获取到Binder代理对象,以访问Service提供的服务。
3、主要作用:
  • 启动Binder线程池,用于与其他进程进行通信。
  • 创建SystemServiceManager,启动各种系统服务

五、Launcher启动

1、Launcher启动流程:

1、启动Launcher的入口为ActivityManagerService的systemReady函数

#SystemServerprivate void startOtherServices() { ...   mActivityManagerService.systemReady(() -> {            Slog.i(TAG, "Making services ready");            traceBeginAndSlog("StartActivityManagerReadyPhase");            mSystemServiceManager.startBootPhase(                    SystemService.PHASE_ACTIVITY_MANAGER_READY);}复制代码

SystemServer中通过ActivityManagerService调用systemReady函数

2、调用到AMS

#ActivityManagerServicepublic void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {    traceLog.traceBegin("PhaseActivityManagerReady");    synchronized(this) {    ......        mStackSupervisor.resumeFocusedStackTopActivityLocked();        mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);        traceLog.traceEnd(); // ActivityManagerStartApps        traceLog.traceEnd(); // PhaseActivityManagerReady    }}复制代码

调用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked函数-->

ActivityStack(用来处理Activity堆栈)的resumeTopActivityUncheckedLocked-->
ActivityStack的resumeTopActivityInnerLocked-->
ActivityStackSupervisor的resumeHomeStackTask-->
AMS的startHomeActivityLocked-->

#AMSboolean startHomeActivityLocked(int userId, String reason) {    //创建Intent    Intent intent = getHomeIntent();    ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);    if (aInfo != null) {        intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));        // Don't do this if the home app is currently being        // instrumented.        aInfo = new ActivityInfo(aInfo);        aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);        ProcessRecord app = getProcessRecordLocked(aInfo.processName,                aInfo.applicationInfo.uid, true);        if (app == null || app.instr == null) {            final String myReason = reason + ":" + userId + ":" + resolvedUserId;            (1)            mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);        }    } else {        Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());    }    return true;}复制代码

(1)调用了ActivityStarter的startHomeActivityLocked方法

3、后续操作

ActivityStackSupervisor的startHomeActivity方法 –>
执行Activity的后续启动逻辑

2、Launcher的item点击

Launcher对应的Activity中是以列表来显示我们的应用图标列表的,并且为每个Item保存了应用的包名和启动Activity类名,这样点击某一项应用图标的时候就可以根据应用包名和启动Activity名称启动我们的App了。

#LauncherActivityprotected void onListItemClick(ListView l, View v, int position, long id) {    Intent intent = intentForPosition(position);    startActivity(intent);}复制代码

调用了startActivity启动了Activity

转载地址:http://anazx.baihongyu.com/

你可能感兴趣的文章
企业会计准则第39号——公允价值计量
查看>>
Linux下查看文件和文件夹大小
查看>>
java.lang.reflect.InvocationTargetException
查看>>
mysql可以用这种方式<<! 输入内容 ! 做成脚本
查看>>
\r与\n的区别
查看>>
发布自己的类库到NuGet
查看>>
linux下配置mysql默认编码utf8
查看>>
spring depends-on
查看>>
android sudio 打包资料汇总
查看>>
使用ASP.Net WebAPI构建REST服务(五)——客户端
查看>>
GIS基础软件及操作(六)
查看>>
Apple Watch 开发详解
查看>>
ACCESS自动编号重新从1开始
查看>>
ES练习代码
查看>>
MvcPager 概述 MvcPager 分页示例 — 标准Ajax分页 对SEO进行优化的ajax分页 (支持asp.net mvc)...
查看>>
UVAlive 3708 Graveyard(最优化问题)
查看>>
携程的配置中心(阿波罗apollo)
查看>>
android Volley 上传文件上传图片
查看>>
drupal cms后台拿shell
查看>>
Kibana里No Marvel Data Found问题解决(图文详解)
查看>>