Android系统启动流程

完整的启动过程:

Android系统启动流程_第1张图片

Android启动流程学习框架:

Android系统启动流程_第2张图片

Android的systemServer zygote ServiceManager

  • ServiceManager最先启动,Zygote再启动,最后启动systemServer。启动顺序决定了进程的依赖性.

  • 启动Zygote目的,就是为了启动systemServer进程

  • systemserver中的service都需要连接sm.所以sm先启动

  • serviceManager只有一个功能就是提供binder通讯服务,Zygote也是一个功能创建java进程.

  • app的启动:app通过binder告诉SystemServer,然后SystemServer告诉Zygote,最后Zygote启动app.

  • app调用service总的来说就是通过serviceManager找到对应服务的binder proxy

  • serviceManager中注册了很多service,每一个service对应一个binder代理---这样就是一个线程一个binder了.

  • zynoteinit 调用startSystemServer创建system_server进程,ss调用handlesystemserverprocess完成自己的使命

Android系统启动流程_第3张图片

图解: Android系统启动过程由上图从下往上的一个过程是由Boot Loader引导开机,然后依次进入 -> Kernel -> Native -> Framework -> App。

notes: 这部分内部不主要。只要把上面的几个图看懂. 知道init启动zygote. zygote创建systemserver,然后等待其他创建进程request. systemserver进程启动60个services.

Loader层:激活Kernel。

启动电源以及系统启动:当电源按下时引导芯片代码将固化在ROM中的引程序Bootloader加载到RAM,然后执行。
引导程序Bootloader:它是Android操作系统开始运行前的 个小程序,负责把系统OS拉起来并运行。
linux内核启动:内核启动时,设置缓存、被保护存储器、计划列表,加载驱动等,为最终调用系统内核准备好环境。

Kernel层:Android内核空间,到这里才刚刚开始进入Android系统。

Bootloader启动Kernel的swapper进程(pid=0),它是内核首个进程,用于初始化进程管理、内存管理、加载各种驱动。更重要的是启动如下两个重要进程:
init进程(pid=1):用户进程的鼻祖
threadd进程(pid=2):内核进程的鼻祖
这层真正大主管是threadd进程,会创建内核工作线程kworkder,软中断线程ksoftirqd,thermal等内核守护进程。

Native层:进入用户空间。

这层init进程(pid=1)是大主管。它负责孵化各种系统级服务、守护进程等。最重要的是孵化出Zygote进程:Java进程的鼻祖。
Media Server进程:负责启动和管理整个C++ framework,包含AudioFlinger,Camera Service等服务。

Framework层:在Native之上,也是用户空间,主要给app层提供api以及系统服务。

这层大主管是 Zygote进程。它负责注册Zygote Socket服务端套接字,加载虚拟机,preloadClasses和preloadResouces。
System Server进程:负责启动和管理整个Java framework,包含AMS、WMS、PMS等服务。

App层:应用程序。

所有的App进程都是由Zygote进程fork生成的。

Init篇

一、Init简介

init进程是Android系统中用户空间的第一个进程(pid=1),它是用户进程的鼻祖,负责孵化各种属性服务、守护进程也包括非常重要的Zygote。init进程是由多个源文件共同组成的,这些文件位于源码目录system/core/init。本文将基于Android7.0源码来分析Init进程。

、Init分析

当内核完成系统设置,它首先在系统文件中寻找”init”文件,最后会调用 /system/core/init/Init.cpp 的 main() 方法。它是init的入口函数。那么来看init.cpp main方法:

int main(int argc, char** argv) {
   …
    //创建文件并挂载
    if (is_first_stage) {
        mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
        mkdir("/dev/pts", 0755);
        mkdir("/dev/socket", 0755);
        mount("devpts", "/dev/pts", "devpts", 0, NULL);
        #define MAKE_STR(x) __STRING(x)
        mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
        mount("sysfs", "/sys", "sysfs", 0, NULL);
    }
    ...
    //初始化属性相关资源
    property_init();
    ...
    //启动属性服务
    start_property_service();
   ...
    Parser& parser = Parser::GetInstance();
    ...
    //解析init.rc配置文件
    parser.ParseConfig("/init.rc");
    ...
    return 0;
}

主要关注两点:初始化和启动属性服务、解析init.rc配置文件并启动zygote进程

2.1 属性服务

Android提供的属性服务类似于Windows平台上注册表管理器的机制,内容采用键值对的形式来记录用户、软件的一些使用信息。即使系统或者软件重启,它还是能够根据之前在注册表中的记录,进行相应的初始化工作。应用程序可以通过这个属性机制,查询或者设置相应的属性。我们可以使用getprop命令来查看当前系统中都有哪些属性。

    //初始化属性相关资源
    property_init();
    ...
    //启动属性服务
    start_property_service();

此处初始化并启动了属性服务,代码细节不追究,了解下结论。

2.2 解析init.rc配置文件并启动zygote进程

2.2.1 了解Android Init Language

init.rc是一个配置文件,内部由Android初始化语言(Android Init Language)编写的脚本。先来学习下AIL:

它主要包含四种类型语句:ActionCommandsServicesOptions

Action(动作): 通过trigger,即以 on开头的语句,决定何时执行相应的service。

on property:=: 当属性值满足条件时触发;...

启动顺序:on early-init -> init -> late-init -> boot

Service(服务):是一个程序,他在初始化时启动,并在退出时重启(可选),由init进程启动,一般运行于另外一个init的子进程,所以启动service前需要判断对应的可执行文件是否存在。init生成的子进程,定义在rc文件,其中每一个service,在启动时会通过fork方式生成子进程。

例: service servicemanager(服务名 ) /system/bin/servicemanager ( 路径)

Command(命令): 要执行的命令

常用的命令:
class_start : 启动属于同一个class的所有服务;
start : 启动指定的服务,若已启动则跳过;
stop : 停止正在运行的服务
...

Option(选项):Options是Services的可选项,与service配合使用

Action与Option配合使用

on  
    
    

举例:

on boot
    ifup lo
    hostname localhost
    domainname localdomain
    class_start default

Service与Command配合使用

service   [  ]* 
          

举例:

service healthd /sbin/healthd
    class core
    critical
    seclabel u:r:healthd:s0
    group root system wakelock

另外还有个import,它的作用是导入其他rc文件。

//init.rc 中
import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /init.usb.configfs.rc
import /init.${ro.zygote}.rc

2.2.2 zygote进程的启动

回到解析init.rc配置文件:

parser.ParseConfig("/init.rc”);

这个parser即init_parse.cpp,通过它对init.rc进行解析。在Android 7.0中对init.rc文件进行了拆分,每个服务一个rc文件。我们要分析的zygote服务的启动脚本则在system/core/rootdir/init.zygoteXX.rc中定义,这里拿64位处理器为例,init.zygote64.rc的代码如下所示

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
   class main
   socket zygote stream 660 root system
   onrestart write /sys/android_power/request_state wake
   onrestart write /sys/power/state on
   onrestart restart audioserver
   onrestart restart cameraserver
   onrestart restart media
   onrestart restart netd
   writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks

通过init_parser.cpp完成整个service解析工作,此处就不详细展开讲解析过程,该过程主要是创建一个名”zygote”的service结构体,一个socketinfo结构体(用于socket通信),以及一个包含4个onrestart的action结构体。

Zygote服务会随着main class的启动而启动,退出后会由init重启zygote,即使多次重启也不会进入recovery模式。zygote所对应的可执行文件是/system/bin/app_process64,通过调用pid =fork()创建子进程,通过execve(svc->args[0], (char)svc->args, (char) ENV),进入App_main.cpp的main()函数。故zygote是通过fork和execv共同创建的。

流程如下:

Android系统启动流程_第4张图片

app_main.cpp的main()方法中,最终通过Androidrumtime来启动zygote进程。

2.3 服务重启

init进程会启动很多native的service,这些service如果不是oneshot的,当service出现异常挂掉后,init需要将其重新启动起来:

Android系统启动流程_第5张图片

具体操作不详细跟了,了解一下结论:

所有的Service里面只有servicemanager ,zygote ,surfaceflinger这3个服务有onrestart关键字来触发其他service启动过程。

//zygote可触发media、netd以及子进程(包括system_server进程)重启
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media
    onrestart restart netd
 
//servicemanager可触发healthd、zygote、media、surfaceflinger、drm重启
service servicemanager /system/bin/servicemanager
    class core
    user system
    group system
    critical
    onrestart restart healthd
    onrestart restart zygote
    onrestart restart media
    onrestart restart surfaceflinger
    onrestart restart drm
 
//surfaceflinger可触发zygote重启
service surfaceflinger /system/bin/surfaceflinger
    class core
    user system
    group graphics drmrpc
    onrestart restart zygote 

所以surfaceflinger,servicemanager、system_server以及zygote自身进程被杀都会触发Zygote重启

总结init的主要工作:

1.创建一些文件夹并挂载设备。

2.初始化和启动属性服务。

3.通过解析init.rc 和 其他对应rc文件,启动对应的系统级进程。其中包括后面要讲的zygote。

Zygote篇

Zygote是由init进程通过解析init.zygote.rc文件而创建的,zygote所对应的可执行程序app_process,所对应的源文件是App_main.cpp,进程名为zygote。

service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    class main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media
    onrestart restart netd

Zygote进程能够重启的地方:

  • servicemanager进程被杀; (onresart)

  • surfaceflinger进程被杀; (onresart)

  • Zygote进程自己被杀; (oneshot=false)

  • system_server进程被杀; (waitpid)

从App_main()开始,Zygote启动过程的函数调用类大致流程如下:

Android系统启动流程_第6张图片

在Android系统中,Zygote是java进程的鼻祖。它在启动时会创建虚拟机,并通过fork(复制进程)的形式来创建应用程序进程和SystemServer进程。

作用: startVM()方法创建虚拟机,再调用startReg()注册JNI函数,启动system_server,runSelectLoop等待创建新进程请求

一、Zygote启动流程

从上篇文章得知init启动Zygote时主要是调用app_main.cpp的main函数中的AppRuntime的start来启动zygote进程的,我们就从app_main.cpp的main函数开始分析。

1.1 AndroidRuntime.cpp

AppRuntime声明在app_main.cpp中,它继承AndroidRuntime,也就是我们调用start其实是调用AndroidRuntime的start函数。

frameworks/base/core/jni/AndroidRuntime.cpp start( )方法中主要工作:

  • 调用startVm函数来创建JavaVm(DVM),并通过调用startReg函数用来为DVM注册JNI

startVm(&mJavaVM, &env, zygote)         
startReg(env)
  • 找到ZygoteInit的main函数,并通过JNI调用,自此Zygote便进入了Java框架层。

     jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
     "([Ljava/lang/String;)V”);
     env->CallStaticVoidMethod(startClass, startMeth, strArray);

1.2 ZygoteInit.java

frameworks/base/core/java/com/android/internal/os/ZygoteInit.java main( )方法中主要工作:

  • 注册Zygote用的Socket,当Zygote进程将SystemServer进程启动后,就会在这个服务端的Socket上来等待ActivityManagerService请求Zygote进程来创建新的应用程序进程。

registerZygoteSocket(socketName);
  • 预加载的资源、类、虚拟机实例等。

preload();
  • 启动SystemServer进程,该进程承载着framework的核心服务。

startSystemServer(abiList, socketName);
  • 循环等待并处理AMS发送来的创建新应用进程请求。如果收到创建应用程序的请求,则调用ZygoteConnection的runOnce函数来创建一个新的应用程序进程。

runSelectLoop(abiList);

整体流程时序图如下:

Android系统启动流程_第7张图片

Zygote进程启动总结:

  1. 解析init.zygote.rc中的参数,创建AppRuntime并调用AppRuntime.start()方法,实际调用AndroidRuntime.start(), 通过startVM()方法创建虚拟机,再调用startReg()注册JNI函数;

  1. 通过JNI方式调用ZygoteInit.main(),第一次进入Java世界;

  1. registerZygoteSocket()建立socket通道,zygote作为通信的服务端,用于响应客户端请求;

  1. preload()预加载通用类、drawable和color资源、openGL以及共享库以及WebView,用于提高app启动效率;

  1. 通过startSystemServer(),fork得力帮手system_server进程,也是上层framework系统服务的运行载体。

  1. zygote功成身退,调用runSelectLoop(),随时待命,当接收到请求创建新进程请求时立即唤醒并执行相应工作。

  1. 同时会因为surfaceflinger,servicemanager,system_server进程被杀而被动触发Zygote重启

  1. 对于Android 5.0以上系统,有两个zygote进程,分别是zygote、zygote64两个进程,从名字可以看出分别对应32位和64位,但是确实是都创建了。

mido:/ # ps | grep zygote
 root      714   1     2176388 47548 poll_sched 7faf1bd660 S zygote64 
 root      715   1     1613320 35496 poll_sched 00f292e3f4 S zygote

二、copy-on-write fork了解一下

以Zygote进程fork应用程序进程为例:

Android系统启动流程_第8张图片

Zygote进程地址空间中包含有预加载资源、预加载类、虚拟机实例等。当Zygote fork一个应用程序进程时,父子进程先是共享相同物理地址资源,但是仅仅只能读不能写,如果此时应用进程开始写操作,那么会从Zygote原物理地址中复制内容到一块新的物理地址上,供应用程序进程使用。这样子进程可以高效而完整地继承父进程内存地址中的数据。

SystemServer篇

从上的Zygote学习中,了解到Zygote进程最后启动了SyetemServer进程,那么这文章就来分析下SystemServer。

notes: 启动所有services

一、SystemServer启动流程

Android系统启动流程_第9张图片

这个过程在zygote进程中,主要包括这么几个内容:

1.1 Zygote fork SystemServer

1.2 当system_server进程创建失败时,将会重启zygote进程:

1.3 Zygote通过信号处理函数SigChldHandler监听所有子进程的存亡

二、SystemServer启动后的工作

Android系统启动流程_第10张图片

关键流程说明:

ZygoteInit.startSystemServer()

fork 子进程 system_ server,进入 system_ server 进程。

ZygoteInit.handleSystemServerProcess()

设置当前进程名为“system_ server”,创建 PathClassLoader 类加载器。

RuntimeInit.zygoteInit()

重定向 log 输出,通用的初始化(设置默认异常捕捉方法,时区等),初始化 Zygote -> nativeZygoteInit()

app_main::onZygoteInit()

proc->startThreadPool(); 启动Binder线程池,这样就可以与其他进程进行通信。

ZygoteInit.main()

开启 DDMS 功能,preload() 加载资源,预加载OpenGL,调用 SystemServer.main() 方法

SystemServer.main()

先初始化 SystemServer 对象,再调用对象的 run() 方法。
SystemServer.run()  
          createSystemContext
          startBootstrapServices(); 
          startCoreServices(); 
          startOtherServices(); 
          Looper.loop();

SystemServer.run

private void run() {
    //当系统时间比1970年更早,就设置当前系统时间为1970年
    if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
        SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
    }

    //变更虚拟机的库文件,对于Android 6.0默认采用的是libart.so
    SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());

    if (SamplingProfilerIntegration.isEnabled()) {
        ...
    }

    //清除vm内存增长上限,由于启动过程需要较多的虚拟机内存空间
    VMRuntime.getRuntime().clearGrowthLimit();

    //设置内存的可能有效使用率为0.8
    VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
    // 针对部分设备依赖于运行时就产生指纹信息,因此需要在开机完成前已经定义
    Build.ensureFingerprintProperty();

    //访问环境变量前,需要明确地指定用户
    Environment.setUserRequired(true);

    //确保当前系统进程的binder调用,总是运行在前台优先级(foreground priority)
    BinderInternal.disableBackgroundScheduling(true);
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
    android.os.Process.setCanSelfBackground(false);

    // 主线程looper就在当前线程运行
    Looper.prepareMainLooper();

    //加载android_servers.so库,该库包含的源码在frameworks/base/services/目录下
    System.loadLibrary("android_servers");

    //检测上次关机过程是否失败,该方法可能不会返回[见小节1.2.1]
    performPendingShutdown();

    //初始化系统上下文 【见小节1.3】
    createSystemContext();

    //创建系统服务管理
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    //将mSystemServiceManager添加到本地服务的成员sLocalServiceObjects
    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);


    //启动各种系统服务
    try {
        startBootstrapServices(); // 启动引导服务【见小节1.4】
        startCoreServices();      // 启动核心服务【见小节1.5】
        startOtherServices();     // 启动其他服务【见小节1.6】
    } catch (Throwable ex) {
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    }

    //用于debug版本,将log事件不断循环地输出到dropbox(用于分析)
    if (StrictMode.conditionallyEnableDebugLogging()) {
        Slog.i(TAG, "Enabled StrictMode for system server main thread.");
    }
    //一直循环执行
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

startBootstrapServices

private void startBootstrapServices() {
    //阻塞等待与installd建立socket通道
    Installer installer = mSystemServiceManager.startService(Installer.class);

    //启动服务ActivityManagerService
    mActivityManagerService = mSystemServiceManager.startService(
            ActivityManagerService.Lifecycle.class).getService();
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);

    //启动服务PowerManagerService
    mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

    //初始化power management
    mActivityManagerService.initPowerManagement();

    //启动服务LightsService
    mSystemServiceManager.startService(LightsService.class);

    //启动服务DisplayManagerService
    mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);

    //Phase100: 在初始化package manager之前,需要默认的显示.
    mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);

    //当设备正在加密时,仅运行核心
    String cryptState = SystemProperties.get("vold.decrypt");
    if (ENCRYPTING_STATE.equals(cryptState)) {
        mOnlyCore = true;
    } else if (ENCRYPTED_STATE.equals(cryptState)) {
        mOnlyCore = true;
    }

    //启动服务PackageManagerService
    mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
            mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    mFirstBoot = mPackageManagerService.isFirstBoot();
    mPackageManager = mSystemContext.getPackageManager();

    //启动服务UserManagerService,新建目录/data/user/
    ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());

    AttributeCache.init(mSystemContext);

    //设置AMS
    mActivityManagerService.setSystemProcess();

    //启动传感器服务
    startSensorService();
}

该方法所创建的服务:ActivityManagerService, PowerManagerService, LightsService, DisplayManagerService, PackageManagerService, UserManagerService, sensor服务.

startCoreServices

private void startCoreServices() {
    //启动服务BatteryService,用于统计电池电量,需要LightService.
    mSystemServiceManager.startService(BatteryService.class);

    //启动服务UsageStatsService,用于统计应用使用情况
    mSystemServiceManager.startService(UsageStatsService.class);
    mActivityManagerService.setUsageStatsManager(
            LocalServices.getService(UsageStatsManagerInternal.class));

    mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();

    //启动服务WebViewUpdateService
    mSystemServiceManager.startService(WebViewUpdateService.class);
}

启动服务BatteryService,UsageStatsService,WebViewUpdateService。

startOtherServices

该方法比较长,有近千行代码,逻辑很简单,主要是启动一系列的服务,这里就不具体列举源码了,在第四节直接对其中的服务进行一个简单分类。

private void startOtherServices() {
        ...
        SystemConfig.getInstance();
        mContentResolver = context.getContentResolver(); // resolver
        ...
        mActivityManagerService.installSystemProviders(); //provider
        mSystemServiceManager.startService(AlarmManagerService.class); // alarm
        // watchdog
        watchdog.init(context, mActivityManagerService); 
        inputManager = new InputManagerService(context); // input
        wm = WindowManagerService.main(...); // window
        inputManager.start();  //启动input
        mDisplayManagerService.windowManagerAndInputReady();
        ...
        mSystemServiceManager.startService(MOUNT_SERVICE_CLASS); // mount
        mPackageManagerService.performBootDexOpt();  // dexopt操作
        ActivityManagerNative.getDefault().showBootMessage(...); //显示启动界面
        ...
        statusBar = new StatusBarManagerService(context, wm); //statusBar
        //dropbox
        ServiceManager.addService(Context.DROPBOX_SERVICE,
                    new DropBoxManagerService(context, new File("/data/system/dropbox")));
         mSystemServiceManager.startService(JobSchedulerService.class); //JobScheduler
         lockSettings.systemReady(); //lockSettings

        //phase480 和phase500
        mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
        mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
        ...
        // 准备好window, power, package, display服务
        wm.systemReady();
        mPowerManagerService.systemReady(...);
        mPackageManagerService.systemReady();
        mDisplayManagerService.systemReady(...);
        
        //重头戏[见小节2.1]
        mActivityManagerService.systemReady(new Runnable() {
            public void run() {
              ...
            }
        });
    }

三、系统服务

startBootstrapServices:引导服务

服务

作用

Installer

系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务

ActivityManagerService

负责大组件的启动、切换、调度。

PowerManagerService

计算系统中和Power相关的计算,然后决策系统应该如何反应

LightsService

管理和显示背光LED

DisplayManagerService

用来管理所有显示设备

UserManagerService

多用户模式管理

SensorService

为系统提供各种感应器服务

PackageManagerService

用来对apk进行安装、解析、删除、卸载等等操作

startCoreServices:核心服务(3个)

服务

作用

BatteryService

管理电池相关的服务

UsageStatsService

收集用户使用每一个APP的频率、使用时常

WebViewUpdateService

WebView更新服务

startOtherServices:其他服务(90多种)

服务

作用

CameraService

摄像头相关服务

AlarmManagerService

全局定时器管理服务

InputManagerService

管理输入事件

WindowManagerService

窗口管理服务

VrManagerService

VR模式管理服务

BluetoothService

蓝牙管理服务

NotificationManagerService

通知管理服务

DeviceStorageMonitorService

存储相关管理服务

LocationManagerService

定位管理服务

AudioService

音频相关管理服务

….

四、SystemServiceManager分析

从名字就很明显知道SystemServiceManager是系统服务管理类,简单了解两个方法:

4.1 startService函数

很简单,就是通过反射创建服务对象,并调用其onStart( )方法启动。

  1. 创建ActivityManagerService.Lifecycle对象;

  1. 调用Lifecycle.onStart()方法。

4.2 startBootPhase函数

Systemserver会将设备启动分成几个阶段,每个阶段service通过继承SytemService实现的onBootPhase方法来做一些对应的操作,相当于一个回调。

Android系统启动流程_第11张图片

ActivityManagerService篇

ActivityManagerService(简称AMS)是Android系统的核心服务之一。它的主要作用是管理系统中所有应用进程以及应用进程中的四大组件。

notes: 建立和SS进程联系;启动子services; 消息循环线程,不断地接收其他进程发给AMS的消息,启动home activity.

一、AMS的启动过程

接上篇SystemServer run( )方法,AMS的启动过程主要包含在如下两个方法中:

private void run() {
...
startBootstrapServices();//创建并启动AMS服务,同时执行AMS启动后的一些初始化工作
startOtherServices();// 进入下个阶段的一些准备工作
...
}

接下来按这两个方法来分析

一、startBootstrapServices( )

1.1 创建并启动AMS服务

private void startBootstrapServices() {
...
//启动AMS服务
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
//设置AMS的系统服务管理器
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
//设置AMS的APP安装器
mActivityManagerService.setInstaller(installer);
//初始化AMS相关的PMS
mActivityManagerService.initPowerManagement();
...
//想ServiceManager注册一系列服务,并创建system_server对应的ProcessRecord并初始化
mActivityManagerService.setSystemProcess();
}

我们知道SystemServiceManager.startService是通过反射创建服务对象,并启动。但是这里传进去的是AMS的Lifecycle。Lifecycle是AMS中的一个静态内部类,它继承SystemService,由它来代理处理AMS的的创建与启动。

AMS.Lifecycle

[-> ActivityManagerService.java]

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

    public Lifecycle(Context context) {
        super(context);
        mService = new ActivityManagerService(context);
    }

    @Override
    public void onStart() {
        mService.start();
    }

    public ActivityManagerService getService() {
        return mService;
    }
}

这样SystemServiceManager间接通过调用Lifecycle创建并启动了AMS服务。

AMS是运行在system_server进程中的Framework服务,经过SystemServiceManager创建的服务会统一保存在队列管理。

1.2、AMS初始化工作

1.2.1 ActivityManagerService的构造方法:

public ActivityManagerService(Context systemContext) {
    mContext = systemContext;
    mFactoryTest = FactoryTest.getMode();//默认为FACTORY_TEST_OFF
    mSystemThread = ActivityThread.currentActivityThread();

    //创建名为"ActivityManager"的前台线程,并获取mHandler
    mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND, false);
    mHandlerThread.start();

    mHandler = new MainHandler(mHandlerThread.getLooper());

    //通过UiThread类,创建名为"android.ui"的线程
    mUiHandler = new UiHandler();

    //前台广播接收器,在运行超过10s将放弃执行
    mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
            "foreground", BROADCAST_FG_TIMEOUT, false);
    //后台广播接收器,在运行超过60s将放弃执行
    mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
            "background", BROADCAST_BG_TIMEOUT, true);
    mBroadcastQueues[0] = mFgBroadcastQueue;
    mBroadcastQueues[1] = mBgBroadcastQueue;

    //创建ActiveServices,其中非低内存手机mMaxStartingBackground为8
    mServices = new ActiveServices(this);
    mProviderMap = new ProviderMap(this);

    //创建目录/data/system
    File dataDir = Environment.getDataDirectory();
    File systemDir = new File(dataDir, "system");
    systemDir.mkdirs();

    //创建服务BatteryStatsService
    mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
    mBatteryStatsService.getActiveStatistics().readLocked();
    ...

    //创建进程统计服务,信息保存在目录/data/system/procstats,
    mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));

    mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
    mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));

    // User 0是第一个,也是唯一的一个开机过程中运行的用户
    mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
    mUserLru.add(UserHandle.USER_OWNER);
    updateStartedUserArrayLocked();
    ...

    //CPU使用情况的追踪器执行初始化
    mProcessCpuTracker.init();
    ...
    mRecentTasks = new RecentTasks(this);
    // 创建ActivityStackSupervisor对象
    mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
    mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);

    //创建名为"CpuTracker"的线程
    mProcessCpuThread = new Thread("CpuTracker") {
        public void run() {
          while (true) {
              synchronized(this) {
                final long now = SystemClock.uptimeMillis();
                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
                if (nextWriteDelay < nextCpuDelay) {
                    nextCpuDelay = nextWriteDelay;
                }
                if (nextCpuDelay > 0) {
                    mProcessCpuMutexFree.set(true);
                    this.wait(nextCpuDelay);
                }
              }
              updateCpuStatsNow(); //更新CPU状态
          }
        }
    };
    ...
}
该过程共创建了3个线程,分别为”ActivityManager”,”android.ui”,”CpuTracker”。

首先,创建了一个名为“ActivityManager”的消息循环线程,不断地接收其他进程发给AMS的消息;并把该消息循环线程与MainHandler绑定,这样,由MainHandler完成消息的具体处理。

然后,创建了一些服务,并在/data/system目录下创建该服务需要的文件或文件夹,具体如下:

服务

服务说明

文件

文件说明

BatteryStatsService

电池状态管理

/data/system/batterystats.bin

记录包括电压在内的各种电池信息

ProcessStatsService

进程状态管理

/data/system/procstats

记录各个进程的状态信息

AppOpsService

应用操作权限管理

/data/system/appops.xml

存储各个app的权限设置和操作信息

ActivityManagerService.start

private void start() {
    Process.removeAllProcessGroups(); //移除所有的进程组
    mProcessCpuThread.start(); //启动CpuTracker线程

    mBatteryStatsService.publish(mContext); //启动电池统计服务
    mAppOpsService.publish(mContext);
    //创建LocalService,并添加到LocalServices
    LocalServices.addService(ActivityManagerInternal.class, new LocalService());
}

1.2.2 ActivityManagerService.setSystemProcess

public void setSystemProcess() {
    try {
        ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
        ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
        ServiceManager.addService("meminfo", new MemBinder(this));
        ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
        ServiceManager.addService("dbinfo", new DbBinder(this));
        if (MONITOR_CPU_USAGE) {
            ServiceManager.addService("cpuinfo", new CpuBinder(this));
        }
        ServiceManager.addService("permission", new PermissionController(this));
        ServiceManager.addService("processinfo", new ProcessInfoService(this));
        ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                "android", STOCK_PM_FLAGS);

        //【见小节2.3.1】
        mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
        synchronized (this) {
            //创建ProcessRecord对象
            ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
            app.persistent = true; //设置为persistent进程
            app.pid = MY_PID;
            app.maxAdj = ProcessList.SYSTEM_ADJ;
            app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
            synchronized (mPidsSelfLocked) {
                mPidsSelfLocked.put(app.pid, app);
            }
            updateLruProcessLocked(app, false, null);//维护进程lru
            updateOomAdjLocked(); //更新adj
        }
    } catch (PackageManager.NameNotFoundException e) {
        throw new RuntimeException("", e);
    }
}

首先,向SystemServiceManager中添加了若干个服务:

服务

服务说明

activity

AMS服务本身

procstats

进程状态管理

meminfo

获取内存信息

gfxinfo

监控分析GPU profiling信息

dbinfo

数据库相关服务

cpuinfo

获取cpu相关信息

permission

权限控制相关服务

然后,调用PMS的getApplicationInfo接口,获取名为”android”的应用程序信息。包名为”android”的apk即/system/framework/framework-res.apk,里面保存着系统GUI美化的相关文件,包括图标,弹出对话框的样式,动作特效,界面布局等。调用installSystemApplicationInfo加载framework-res.apk文件。

接着,调用newProcessRecordLocked新建一个ProcessRecord 对象app。ProcessRecord用来描述一个进程的所有信息,包括该进程的所有activity和service等。在这里就是system_server(AMS就是在system_server进程中运行的)。创建后,对app的一些成员变量进行初始化,包括设置为常驻内存运行;设置system_server的pid等。

最后,调用mProcessNames.put()将创建的ProcessRecord 对象app加入到ProcessMap< ProcessRecord >类型的成员变量mProcessNames中。这里,app.processName=“system”。

这样,AMS就得到了system_server的ProcessRecord,以后AMS也可以管理system_server了。

setSystemProcess()过程向servicemanager注册了如下这个binder服务

服务名

类名

功能

activity

ActivityManagerService

AMS

procstats

ProcessStatsService

进程统计

meminfo

MemBinder

内存

gfxinfo

GraphicsBinder

图像信息

dbinfo

DbBinder

数据库

cpuinfo

CpuBinder

CPU

permission

PermissionController

权限

processinfo

ProcessInfoService

进程服务

usagestats

UsageStatsService

应用的使用情况

想要查看这些服务的信息,可通过dumpsys <服务名>命令。比如查看CPU信息命令dumpsys cpuinfo

二、startOtherServices( )

2.1 systemServer触发AMS的准备工作:

private void startOtherServices() {
  ...
  //安装系统Provider 【见小节2.4.1】
  mActivityManagerService.installSystemProviders();
  ...

  //phase480 && 500
  mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
  mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
  ...

  //【见小节3.1】
  mActivityManagerService.systemReady(new Runnable() {
     public void run() {
         //phase550
         mSystemServiceManager.startBootPhase(
                 SystemService.PHASE_ACTIVITY_MANAGER_READY);
         ...
         //phase600
         mSystemServiceManager.startBootPhase(
                 SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
         ...
      }
  }
}

AMS.installSystemProviders

public final void installSystemProviders() {
    List providers;
    synchronized (this) {
        ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
        providers = generateApplicationProvidersLocked(app);
        if (providers != null) {
            for (int i=providers.size()-1; i>=0; i--) {
                ProviderInfo pi = (ProviderInfo)providers.get(i);
                //移除非系统的provider
                if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
                    providers.remove(i);
                }
            }
        }
    }
    if (providers != null) {
        //安装所有的系统provider
        mSystemThread.installSystemProviders(providers);
    }

    // 创建核心Settings Observer,用于监控Settings的改变。
    mCoreSettingsObserver = new CoreSettingsObserver(this);
}

2.2 mActivityManagerService.systemReady()

主要分三个阶段来讲:

public void systemReady(final Runnable goingCallback) {
    before goingCallback; // 见小节[3.1]
    goingCallback.run(); // 见小节[3.2]
    after goingCallback; // 见小节[3.3]
}

2.2.1 before goingCallback

ynchronized(this) {
    if (mSystemReady) { //首次为flase,则不进入该分支
        if (goingCallback != null) {
                goingCallback.run();
            }
        return;
    }

    mRecentTasks.clear();
    //恢复最近任务栏的task
    mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
    mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
    mTaskPersister.startPersisting();

    if (!mDidUpdate) {
        if (mWaitingUpdate) {
            return;
        }
        final ArrayList doneReceivers = new ArrayList();
        //处于升级过程【见小节3.1.1】
        mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
            public void run() {
                synchronized (ActivityManagerService.this) {
                    mDidUpdate = true;
                }
                showBootMessage(mContext.getText(
                        R.string.android_upgrading_complete),
                        false);
                writeLastDonePreBootReceivers(doneReceivers);
                systemReady(goingCallback);
            }
        }, doneReceivers, UserHandle.USER_OWNER);

        if (mWaitingUpdate) {
            return;
        }
        mDidUpdate = true;
    }

    mAppOpsService.systemReady();
    mSystemReady = true;
}

ArrayList procsToKill = null;
synchronized(mPidsSelfLocked) {
    for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
        ProcessRecord proc = mPidsSelfLocked.valueAt(i);
        //非persistent进程,加入procsToKill
        if (!isAllowedWhileBooting(proc.info)){
            if (procsToKill == null) {
                procsToKill = new ArrayList();
            }
            procsToKill.add(proc);
        }
    }
}

synchronized(this) {
    if (procsToKill != null) {
        //杀掉procsToKill中的进程, 杀掉进程且不允许重启
        for (int i=procsToKill.size()-1; i>=0; i--) {
            ProcessRecord proc = procsToKill.get(i);
            removeProcessLocked(proc, true, false, "system update done");
        }
    }
    mProcessesReady = true; //process处于ready状态
}
Slog.i(TAG, "System now ready");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
     SystemClock.uptimeMillis());

该阶段的主要功能:

  • 向PRE_BOOT_COMPLETED的接收者发送广播;

  • 杀掉procsToKill中的进程, 杀掉进程且不允许重启;

  • 此时,系统和进程都处于ready状态;

2.2.2 goingCallback.run()

此处的goingCallback,便是在startOtherServices()过程中传递进来的参数
private void startOtherServices() {
  ...
  mActivityManagerService.systemReady(new Runnable() {
    public void run() {
      //phase550
      mSystemServiceManager.startBootPhase(
              SystemService.PHASE_ACTIVITY_MANAGER_READY);

      mActivityManagerService.startObservingNativeCrashes();
      //启动WebView
      WebViewFactory.prepareWebViewInSystemServer();
      //启动系统UI【见小节3.2.1】
      startSystemUi(context);

      // 执行一系列服务的systemReady方法
      networkScoreF.systemReady();
      networkManagementF.systemReady();
      networkStatsF.systemReady();
      networkPolicyF.systemReady();
      connectivityF.systemReady();
      audioServiceF.systemReady();
      Watchdog.getInstance().start(); //Watchdog开始工作

      //phase600
      mSystemServiceManager.startBootPhase(
              SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);

      //执行一系列服务的systemRunning方法
      wallpaper.systemRunning();
      inputMethodManager.systemRunning(statusBarF);
      location.systemRunning();
      countryDetector.systemRunning();
      networkTimeUpdater.systemRunning();
      commonTimeMgmtService.systemRunning();
      textServiceManagerService.systemRunning();
      assetAtlasService.systemRunning();
      inputManager.systemRunning();
      telephonyRegistry.systemRunning();
      mediaRouter.systemRunning();
      mmsService.systemRunning();
    }
  });
}

这部分是回调到systemServer startOtherServices中完成的:

此阶段主要工作总结:

  • startBootPhase:550(PHASE_ACTIVITY_MANAGER_READY),回调相应onBootPhase()方法;

  • 启动WebView进程;

  • 启动systemui服务;

  • startBootPhase:600(PHASE_THIRD_PARTY_APPS_CAN_START),回调相应onBootPhase()方法;

  • 执行一系列服务的systemReady方法;

  • 执行一系列服务的systemRunning方法;

startSystemUi

static final void startSystemUi(Context context) {
    Intent intent = new Intent();
    intent.setComponent(new ComponentName("com.android.systemui",
                "com.android.systemui.SystemUIService"));
    context.startServiceAsUser(intent, UserHandle.OWNER);
}

启动服务”com.android.systemui/.SystemUIService”

2.2.3 after goingCallback.run()

//启动【见小节3.3.1】
mSystemServiceManager.startUser(mCurrentUserId);
synchronized (this) {
    if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
        //通过pms获取所有的persistent进程
        List apps = AppGlobals.getPackageManager().
            getPersistentApplications(STOCK_PM_FLAGS);
        if (apps != null) {
            int N = apps.size();
            int i;
            for (i=0; i

此阶段主要工作总结:

  • 回调所有SystemService的onStartUser()方法;

  • 启动persistent进程;

  • 启动home Activity;

  • 发送广播USER_STARTED和USER_STARTING;

  • 发送广播USER_SWITCHED;

最后画了个简单时序图总结下AMS启动流程:

Android系统启动流程_第12张图片

AMS.systemReady()的大致过程如下:

public final class ActivityManagerService{

    public void systemReady(final Runnable goingCallback) {
        ...//更新操作
        mSystemReady = true; //系统处于ready状态
        removeProcessLocked(proc, true, false, "system update done");//杀掉所有非persistent进程
        mProcessesReady = true;  //进程处于ready状态

        goingCallback.run(); //这里有可能启动进程

        addAppLocked(info, false, null); //启动所有的persistent进程
        mBooting = true;  //正在启动中
        startHomeActivityLocked(mCurrentUserId, "systemReady"); //启动桌面
        mStackSupervisor.resumeTopActivitiesLocked(); //恢复栈顶的Activity
    }
}

再说一说mProcessesReady

startProcessLocked()过程对于非persistent进程必须等待mProcessesReady = true才会真正创建进程,否则进程放入mProcessesOnHold队列。 当然以下情况不会判断mProcessesReady:

  • addAppLocked()启动persistent进程; //但此时已经mProcessesReady;

  • finishBooting()启动on-hold进程; //但此时已经mProcessesReady;

  • cleanUpApplicationRecordLock() //启动需要restart进程,前提是进程已创建;

  • attachApplicationLocked() //绑定Bind死亡通告失败,前台同样是进程要已创建。

还有一个特殊情况,可以创建进程:processNextBroadcast()过程对于flag为FLAG_RECEIVER_BOOT_UPGRADE的广播拉进程 ,只在小节3.1.1的升级过程会出现。

由此可见,mProcessesReady在没有ready前,则基本没有应用进程。

Launcher篇

经过之前Android系统一系列启动流程,终于到了用户可视化操作界面了,即:Home桌面了,它是一个应用程序,叫Launcher。它主要展示一个个应用的快捷图标,并且通过点击图标来启动相应的应用程序。那么这篇文章就来解读下它。

notes:基本没有什么有用的. Launcher是用工作区的形式来显示系统安装的应用程序的快捷图标,每一个工作区都是来描述一个抽象桌面的.它由n个屏幕组成,每个屏幕又分n个单元格,每个单元格用来显示一个应用程序的快捷图标

一、Launcher的启动流程

接上篇AMS最后讲到的startHomeActivityLocked

public void systemReady(final Runnable goingCallback){
 ...
   startHomeActivityLocked(currentUserId, "systemReady");
 ...
}
boolean startHomeActivityLocked(int userId, String reason) {
    Intent intent = getHomeIntent();
    ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
    if (aInfo != null) {
        intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, [aInfo.name](http://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.instrumentationClass == null) {
            intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
            mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
}}       }

首先是调用getHomeIntent()方法,看一下getHomeIntent是如何实现构造Intent对象的:

Intent getHomeIntent() {
    Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
    intent.setComponent(mTopComponent);
    intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
    if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
        intent.addCategory(Intent.CATEGORY_HOME);
    }
    return intent;
}

启动Launcher的Intent对象中添加了Intent.CATEGORY_HOME常量,这个其实是一个launcher的标志,一般系统的启动页面Activity都会在androidManifest.xml中配置这个标志。

看下Launcher的AndroidManifest.xml:

//packages/apps/Launcher3/AndroidManifest.xml

    
        
        
        
        
    

最后通过如下代码启动home的Activity:

mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);

具体流程牵扯到Activity的启动流程,之后会有专门章节来总结,这里就简单列举下之后的执行路径:

ActivityStarter.startHomeActivityLocked 
|
ActivityStarter.startActivityLocked  验证intent、Class、Permission等 ,保存将要启动的Activity的Record
|
ActivityStarter.doPendingActivityLaunchesLocked
|
ActivityStarter.startActivityUnchecked 检查将要启动的Activity的launchMode和启动Flag ,根据launcheMode和Flag配置task
|
ActivityStack.startActivityLocked
|
ActvityStack.startActivityLocked 任务栈历史栈配置
|
ActivityStack.resumeTopActivityInnerLocked() 查找要进入暂停的Activity
|
ActivityStack.startPausingLocked() 通过ipc告诉要暂停的Activity进入暂停
|
ActivityThread.handlePauseActivity() 1正式让之前的Activity暂停 2 告诉AMS已经暂停完成
|
ActivityManagerService.activityPaused()
|
ActivityStack.activityPausedLocked()
|
ActivityStackSuperVisor.resumeTopActivitiesLocked()
|
ActivityStack.resumeTopActivityLocked() 验证是否该启动的Activity所在进程和app是否存在,若存在,直接启动,否则,准备创建该进程
|
ActivityStackSuperVisor.startSpecificActivityLocked() 该进程不存在,创建进程
|
ActivityManagerService.startProcessLocked()
|
ActivityManagerService.startProcessLocked() 通过Process.start(“android.app.ActivityThread”)启动进程
|
ActivityThread.main()
|
ActivityThread.attach()  创建了 Instrumentation()
|
IActivityManager.attachApplication()
|
ActivityStackSuperVisor.attachApplicationLocked() 准备启动应用,先查找MainActivity
|
ActivityStackSuperVisor.realStartActivityLocked() IPC通知ActivityThread
|
ActivityThread.scheduleLaunchActivity()  H 发消息 sendMessage(H.LAUNCH_ACTIVITY, r);
|
ActivityThread.handleLaunchActivity()
|
ActivityThread.performLaunchActivity()
|
Instrumentation.newActivity() 创建activity
|
activity.attach( )
|
Instrumentation.callActivityOnCreate 最终执行Activity onCreate

二、launcher中应用图标显示流程

经过前面的启动分析,我们终于进入到Launcher的主Activity了

public class Launcher extends Activity{
    private LauncherModel mModel;
    onCreate(Bundle savedInstanceState){
       ...
      LauncherAppState app =LauncherAppState.getInstance(); //LauncherAppState创建单例对象
       …
       mModel = app.setLauncher(this);
       setContentView(R.layout.launcher); //设置布局
        …
//load显示数据
        // We only load the page synchronously if the user rotates (or triggers a
        // configuration change) while launcher is in the foreground
        mModel.startLoader(mWorkspace.getRestorePage());
}...}}

看样子核心功能都在LauncherModel里:

先看看 mModel = app.setLauncher(this);

LauncherModel setLauncher(Launcher launcher) {
    getLauncherProvider().setLauncherProviderChangeListener(launcher);
    mModel.initialize(launcher);
    mAccessibilityDelegate = ((launcher != null) && Utilities.ATLEAST_LOLLIPOP) ?
        new LauncherAccessibilityDelegate(launcher) : null;
    return mModel;
}

主要做了个初始化操作:

//LauncherModel
public void initialize(Callbacks callbacks) {
        unbindItemInfosAndClearQueuedBindRunnables();
        mCallbacks = new WeakReference(callbacks);
}

在initialize函数中会将Callbacks,也就是传入的Launcher 封装成一个弱引用对象。

因此我们得知mCallbacks变量指的是封装成弱引用对象的Launcher,这个mCallbacks后文会用到它.

回到onCreate 看看后面LauncherModel.startLoader方法:

...
@Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");//创建了具有消息循环的线程HandlerThread对象
    static {
        sWorkerThread.start();
    }
    @Thunk static final Handler sWorker = new Handler(sWorkerThread.getLooper());//创建了Handler,并且传入HandlerThread的Looper。
...
   public void startLoader(int synchronousBindPage, int loadFlags) {
        InstallShortcutReceiver.enableInstallQueue();
                stopLoaderLocked();
                mLoaderTask=new LoaderTask(mApp.getContext(),loadFlags);//创建LoaderTask
                if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE
                        && mAllAppsLoaded && mWorkspaceLoaded && !mIsLoaderTaskRunning) {
                    mLoaderTask.runBindSynchronousPage(synchronousBindPage);
                } else {
                    sWorkerThread.setPriority(Thread.NORM_PRIORITY);
                    sWorker.post(mLoaderTask);//将LoaderTask作为消息发送给HandlerThread 
}            }

LoaderTask类实现了Runnable接口,当LoaderTask所描述的消息被处理时则会调用它的run函数,代码如下所示:

//LauncherModel
private class LoaderTask implements Runnable {
...
final List apps = mLauncherApps.getActivityList(null, user);
...
mHandler.post(new Runnable() {
       public void run() {
               mIsLoaderTaskRunning = true;
           keep_running: {
               loadAndBindWorkspace();//调用loadAndBindWorkspace函数用来加载工作区信息
               if (mStopped) {
                   break keep_running;
               }
               waitForIdle();
                loadAndBindAllApps();//用来加载系统已经安装的应用程序信息
           }
           mContext = null;
           mIsLoaderTaskRunning = false;
           mHasLoaderCompletedOnce = true;
}}...}

mLauncherApps.getActivityList执行的是

//LauncherAppsmService.getLauncherActivities(packageName, user);

而mService 是:

ILauncherApps.Stub.asInterface(
        ServiceManager.getService(Context.LAUNCHER_APPS_SERVICE)));

也就是最终由LauncherAppService执行getLauncherActivities:

@Override
public ParceledListSlice getLauncherActivities(String packageName, UserHandle user) throws RemoteException {
    final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
    mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
    mainIntent.setPackage(packageName);
    long ident = Binder.clearCallingIdentity();
    try {
        List apps = mPm.queryIntentActivitiesAsUser(mainIntent,
                PackageManager.MATCH_DIRECT_BOOT_AWARE
                        | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
                user.getIdentifier());
        return new ParceledListSlice<>(apps);
    } finally {
        Binder.restoreCallingIdentity(ident);
    }
}

最终由PMS 执行queryIntentActivitiesAsUser 去获取要展示的APP信息.(这部分之后总结PMS再细说)

Launcher是用工作区的形式来显示系统安装的应用程序的快捷图标,每一个工作区都是来描述一个抽象桌面的.它由n个屏幕组成,每个屏幕又分n个单元格,每个单元格用来显示一个应用程序的快捷图标。这里loadAndBindWorkspace不分析,直接看加载数据相关的loadAndBindAllApps, loadAndBindAllApps又会调用loadAllApps:

//LauncherModel
  private void loadAllApps() {
...
            mHandler.post(new Runnable() {
            public void run() {
                final long bindTime = SystemClock.uptimeMillis();
                final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
                    callbacks.bindAllApplications(added);
            }
        });...}

调用callbacks的bindAllApplications函数,在前面我们得知这个callbacks实际是指向Launcher的,因此我们来查看Launcher的bindAllApplications函数:

//Launcher
public void bindAllApplications(final ArrayList apps) {
        mAppsView.setApps(apps);//
        mLauncherCallbacks.bindAllApplications(apps);
}

那mAppsView是什么?

mAppsView = (AllAppsContainerView) findViewById(R.id.apps_view);

apps_view对应的是一个自定义控件:

com.android.launcher3.allapps.AllAppsContainerView

public AllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {
    Resources res = context.getResources();
    mLauncher = (Launcher) context;
    mSectionNamesMargin = res.getDimensionPixelSize(R.dimen.all_apps_grid_view_start_margin);
    mApps = new AlphabeticalAppsList(context);
    mAdapter = new AllAppsGridAdapter(mLauncher, mApps, this, mLauncher, this);
    mApps.setAdapter(mAdapter);
    mLayoutManager = mAdapter.getLayoutManager();
    mItemDecoration = mAdapter.getItemDecoration();
    mRecyclerViewTopBottomPadding =
            res.getDimensionPixelSize(R.dimen.all_apps_list_top_bottom_padding);
    mSearchQueryBuilder = new SpannableStringBuilder();
    Selection.setSelection(mSearchQueryBuilder, 0);
}

再看看mApps初始化的地方:

publicAllAppsContainerView(Context context, AttributeSet attrs, int defStyleAttr) {Resourcesres= context.getResources();    mLauncher = (Launcher) context;    mSectionNamesMargin = res.getDimensionPixelSize(R.dimen.all_apps_grid_view_start_margin);    mApps = newAlphabeticalAppsList(context);    mAdapter = newAllAppsGridAdapter(mLauncher, mApps, this, mLauncher, this);    mApps.setAdapter(mAdapter);    mLayoutManager = mAdapter.getLayoutManager();    mItemDecoration = mAdapter.getItemDecoration();    mRecyclerViewTopBottomPadding =            res.getDimensionPixelSize(R.dimen.all_apps_list_top_bottom_padding);    mSearchQueryBuilder = newSpannableStringBuilder();    Selection.setSelection(mSearchQueryBuilder, 0);}

最后再看看AllAppsContainerView的onFinishInflate方法:

//AllAppsContainerView
@Override
    protected void onFinishInflate() {
        super.onFinishInflate();
...
        // Load the all apps recycler view
        mAppsRecyclerView = (AllAppsRecyclerView) findViewById(R.id.apps_list_view);
        mAppsRecyclerView.setApps(mApps);//2
        mAppsRecyclerView.setLayoutManager(mLayoutManager);
        mAppsRecyclerView.setAdapter(mAdapter);//3
        mAppsRecyclerView.setHasFixedSize(true);
        mAppsRecyclerView.addOnScrollListener(mElevationController);
        mAppsRecyclerView.setElevationController(mElevationController);
...
    }

onFinishInflate函数在加载完xml文件时就会调用。AllAppsRecyclerView设置数据,并setAdapter。

一张图总结Launcher整个启动过程以及数据显示过程:

Android系统启动流程_第13张图片

你可能感兴趣的:(android,android,studio,ide)