Android知识点1--Android的启动过程剖析

451 阅读5分钟

1. Android 启动过程是什么样?

Android 系统架构包括 Linux Kernel、HAL、Native C/C++ Library、Android Runtime、Java Api Framework、SystemApps 六块内容。

1.1. 开机过程:

  • 启动电源以及系统启动

  • 加载引导程序BootLoader到RAM中,拉起系统OS

  • 内核启动后,查找init.rc文件,启动init进程

  • init进程主要用来初始化和启动属性服务,也用来启动Zygote进程

    init进程的main方法中涉及几个重要函数:

    • propery_init 对属性服务进行初始化
    • singal_handler_init 设置子进程信号处理函数,防止子进程成为僵尸进程 (父进程fork出子进程后,子进程虽然已经退出,但在系统进程表中还保存一定的信息)
    • parser.ParseConfig 解析init.rc文件
    • restart_processes 重启死去的进程

init进程启动Zygote进程,zygote执行程序是app_main.cpp,通过以下代码启动

runtime.start("com.android.internal.os.ZygoteInit",args,zynote)

init进程初始化属性服务并启动属性服务,propery_init()、start_property_service() 在linux新内核中,epoll替换了select,epoll是linux内核为处理大批量文件描述符而做了改进的poll,是linux下多路复用I/O接口select/poll的增强版本。内部保存事件的数据是红黑树,select采用数组保存。

1.1.1. init进程启动总结:

  • 创建和挂载启动所需的文件目录
  • 初始化和启动属性服务
  • 解析init.rc配置文件并启动zygote进程

1.1.2. Zygote进程

Zygote进程名为"app_process",zygote进程启动后会修改为"zygote",通过fork的形式来创建DVM/ART、应用程序进程、SystemServer进程

Zynote启动过程.jpg

1.1.2.1. AndroidRunTime的start方法中做了什么事情呢?

  • startVM : 启动Java虚拟机
  • startReg : 为Java虚拟机注册JNI方法
  • 获取Zygote的className ,com.android.internal.os.ZygoteInit
  • 找到Java层的ZygoteInt类
  • 通过JNI调用ZygoteInit的main方法,Zygote从Native层进入了Java框架层

1.1.2.2. ZygoteInit的main方法做了什么事情呢?

  • zygoteServer.registerServerSocket : 创建一个Server端的Socket,socket名称为"zygote"
  • preload : 预加载类和资源
  • startSystemServer: 启动SystemServer进程
  • zygoteServer.runSelectLoop : 等待AMS请求Zygote进程创建新的应用程序

1.1.2.3. SystemServer进程处理过程

SystemServer进程用于创建系统服务,如AMS、PMS、WMS等

Zygote进程启动了SystemServer进程,那么Zygote是如何处理SystemServer进程的呢?


startSystemServer中完成两件事:

*   关闭Zygote进程创建的Socket,这个Socket对于SystemServer没有用处
*   调用handleSystemServerProcess启动SystemServer进程

handleSystemServerProcess完成两件事:

*   调用 createPathClassLoader ,创建PathClassLoader
*   调用 ZygoteInit.zygoteInit ,在此方法中完成两件事情

    *   ZygoteInit.nativeZygoteInit: 启动Binder线程池
        ***调用Native层的AndroidRuntime的onZygoteInit创建Binder线程池,这样SystemServer就可以通过Binder和其他进程进行通信了。***

    ```C++
    sp<ProcessState> proc = ProcessState::self();
    proc->startThreadPool();
    ```

    *   RuntimeInit.applicationInit: 进入SystemServer的main方法中
*   在applicationInit方法的invokeStaticMain方法中通过反射得到SystemServer类

    ```Java
      private static void invokeStaticMain(...){
          // 通过反射找到SystemServer类
          cl = Class.forName(className, true, classLoader);
          ...
          // 找到SystemServer的main方法
          m = cl.getMethod("main", new class[] {String[].class});
          ...
          // 最后抛出一个异常,这个异常会在ZygoteInit的main方法被捕获
          // 这个异常的处理会清除设置过程需要的堆栈帧,让SystemServer的main方法看起来像是SystemServer进程的入口方法
          throw new Zygote.MethodAndArgsCaller(m,argv);
      }
    ```

    *   至此,System进程就进入到SystemServer的main方法中。

#### 1.1.2.4. SystemServer进程的解析

进入到SystemServer.main方法中

```Java
public sattic void main(String[] args){
    new SystemServer.run();
}
private void run (){
    try {
        ...
        // 创建消息Looper
        Looper.prepareMainLooper();
        // 加载动态库libandroid_servers.so
        System.loadLibrary("android_servers");
        ...
        // 初始化系统上下文
        createSystemContext();
        // 创建系统服务管理,对系统服务进行创建、启动和生命周期管理
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
        ...
    } finally {
        ...
    }

    try {
        ...
        // 启动引导服务(如AMS、PMS、PowerManagerService、DisplayManagerService...)
        startBootstrapServices();
        // 启动核心服务(如日志、电池、WebView...)
        startCoreServices();
        // 启动其他服务(如WMS、IMS、相机、蓝牙、通知、定位)
        startOtherServices();

    }
}

在SystemServiceManager中有一个mServices的arrayList变量用来保存各种系统服务。 通过SystemServiceManager.startService(xxxx.class)可以完成把某个Service服务添加到mServices中,完成该服务的注册。还可以通过比如调用PackageManagerService.main()这种形式来完成启动系统服务。

public static PackageManagerService main(Context context, Installer installer, boolean factoryTest, boolean onlyCore){
    ...
    // 创建PackageManagerService
    PackageManagerService m = new PackageManagerService(context, installer, factoryTest, onlyCore);
    m.enableSystemUserPackages();
    // 注册到ServiceManager中
    ServiceManager.addService("package",m);
    return m;
}

ServiceManager 用来管理系统中的各种Service ,用于系统C/S架构中的Binder通信机制。

1.1.2.5. SystemServer 进程总结

  • 启动Binder线程池,这样就可以与其他进程进行通信
  • 创建SystemServiceManager,完成对系统服务的创建、启动和生命周期管理
  • 启动引导服务、核心服务、其他服务

1.2. Launcher的启动

Launcher在启动过程中会请求PMS获取系统已安装应用信息,然后将其封装成一个快捷图标列表显示在系统屏幕上。

SystemService进程在启动过程中会启动PMS,PMS启动后会把应用程序都安装成功,而Launcher是在AMS启动后被它启动起来的。

image.png

通过层层调用,最终调用到startActivityStarter方法中,剩下的就跟普通的Activity的调用类似了,最终会调用到Launcher的onCreate方法中。

Launcher是如何显示应用图标的?

protected void onCreate(...){
    ...
    LauncherAppState app = LauncherAppState.getInstance();
    ...
    mModel = app.setLauncher(this);
    ...
    mModel.startLoader(...);
}

LauncherModel setLauncher(Launcher this){
    getLocalProvider(mContext)。setLauncherProviderChangeListener(launcher);
    mModel.initialize(launcher);
    return mModel;
}

public void initialize(Callbacks callbacks){
    synchronized(mLock){
        ...
        // 把传入的Launcher封装成弱引用对象
        mCallbacks = new WeakReference<Callbacks>(callbacks);
    }
}

在LauncherModel中,创建了sWorkerThread
HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
Handler sWorker = new Handler(sWorkerThread.getLooper());

public void startLoader(...){
    ...
    mLoaderTask = new LoaderTask(mApp, isLaunching);
    ...
    // 将LoaderTask作为消息传递给HandlerThread
    sWorker.post(mLoaderTask);
}

private class LoaderTask implements Runnable {
    ...
    // 加载工作区信息
    loadWorkspace();
    ...
    // 绑定工作区信息
    bindWorkspace(mPageToBindFirst);
    ...
    // 加载系统已经安装好的应用程序信息
    loadAllApps();
}

private void loadAllApps(){
    mHandler.post(new Runnable {
        ...
        // 这个callbacks实际指向就是Launcher
        callbacks.bindAllApplications(added);
    })
}

public void bindAllApplications(final ArrayList<AppInfo> apps){
    ...
    if(mAppViews != null){
        // mAppViews类型为AllAppsContainerView
        mAppViews.setApps(apps);
    }
}

最终会调用到AllAppsContainerView的onFinishInflate方法中
protected void onFinishInflate() {
    ...
    mAppsRecyclerView.setApps(mApps);
    mAppsRecyclerView.setLayoutManager(...);
    mAppsRecyclerView.setAdapter(...);
}

现在应用程序的快捷图标的列表就显示在屏幕上了。

1.2.1. 总结:Android的启动流程

  • 启动电源以及系统启动
  • 引导程序BootLoader
  • Linux内核启动
  • init进程启动
  • Zygote进程启动
  • SystemServer进程启动
  • Launcher启动