Android系统启动

分析的源码基于android-8.0.0_r4

《安卓进阶解密》读书笔记

Android系统启动

在Android系统启动的流程中,主要介绍下面几点

  • init进程启动过程
  • Zygote进程启动过程
  • SystemServer进程启动过程
  • Launcher启动过程

其中,init、Zygote、SystemServer进程启动的关系密切,这里先给出流程图

Android系统启动_1

Launcher启动的部分时序图如下

Android系统启动_2

init进程启动过程

init进程是Android系统中用户空间的第一个进程,进程号为1

init进程启动之前,会先做下面几件事情

  1. 启动电源以及系统启动
  2. 执行引导程序BootLoader
  3. Linux内核启动
  4. init进程启动

当我们按下启动电源时,系统启动后会加载引导程序,引导程序又启动Linux内核,在Linux内核加载完成后,第一件事就是要启动init进程.

init进程启动主要做的事情

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

大致过程

先查看init进程的入口函数main,在system/core/init/init.cpp

int main(int argc, char** argv) {
    ...
    //1.创建和挂载启动所需的文件目录    
    mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
    mkdir("/dev/pts", 0755);
    mkdir("/dev/socket", 0755);
    mount("devpts", "/dev/pts", "devpts", 0, NULL);   
    ...
    //2.对属性服务进行初始化
    property_init();    
    ...
    //3.设置子进程信号处理函数
    signal_handler_init();
    //4.启动属性服务
    start_property_service()
    ...    
    if (bootscript.empty()) {
        //5.解析init.rc配置文件
        parser.ParseConfig("/init.rc");
        ...
    }else{
        ...
    }
    ...
    while(true){
        ...
        //6.重启死去的进程    
        restart_processes();    
        ...    
    }    
}
  • 第2、4步:在Windows中,有注册表管理器,注册表的内容用于记录用户、软件的一些使用信息。Android也有类似的机制,称为属性服务,用户可以读取属性的信息,也可以添加属性,或者更新属性值

  • 第3、6步:如果有子进程异常退出,第3步设置的子进程信号处理函数,会清除子进程相关的信息,并重启子进程的部分服务,可以防止子进程变成"僵尸进程",而子进程本身会在第6步重启

  • 第5步:解析init.rc配置文件

解析与启动

解析:解析init.rc文件

启动:启动Zygote

init.rc是由Android初始化语言(Android Init Language)编写的脚本,包含5种类型的语句:Action、Command、Service、Option、Import。这里分析Zygote相关的,Zygote的启动脚本对应的是Service类型语句,Service类型语句格式如下

# <name>        service的名字
# <pathname>    执行程序路径
# <argument>    传递参数
# <option>      service的修饰符,它将影响服务何时、如何启动service
service <name> <pathname> [ <argument> ]* 
   <option>
   <option>
   ...

以64位处理器为例,Zygote对应的启动脚本为init.zygote64.rc

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc
    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
    onrestart restart wificond
    writepid /dev/cpuset/foreground/tasks

可以获取到的信息

  • 服务的名称为zygote
  • 执行程序的路径为/system/bin/app_process64
  • 服务的classname为main
  • Zygote重启时,要重启一些进程相关服务(onrestart restart xxx

init.zygote64.rc解析完成之后,会将Zygote对应的Service,添加到Service链表里,在system/core/init/service.cpp中,如下

void ServiceManager::AddService(std::unique_ptr<Service> service) {
    ...
    services_.emplace_back(std::move(service));
}

service_就是Zygote对应的Service

接着,在init.rc中有Command类型的语句,用于启动Zygote,最终会调用到Service类的Start方法,在system/core/init/service.cpp

bool Service::Start() {
	...
    //如果子进程没有启动,则调用fork函数创建子进程    
    pid = fork();
    //子进程得到的pid == 0,下面if语句中的代码会在子进程中执行;init进程不会执行下面的if语句
    if (pid == 0) {
        ...
        if (execve(strs[0], (char**) &strs[0], (char**) ENV) < 0) {
            ...
        }
        ...
    }
    ...
}

调用execve后,Service子进程就会启动,进入Service的main函数中,Zygote的执行程序路径为/system/bin/app_process64,对应文件frameworks/base/cmds/app_process/app_main.cpp,所以会进入app_main.cpp的main函数中,接下来就进入Zygote的进程启动了~~

Zygote进程启动过程

  • Zygote也称为孵化器,Android系统中,Dalvik虚拟机(DVM)和ART、应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的。
  • 应用程序进程与SystemServer进程,均由Zygote进程Fork所得,由于Zygote进程在启动时会创建DVM或者ART,因此通过Fork所创建的应用程序进程和SystemServer进程,可以在内部获取一个DVM或者ART的实例副本,避免启动虚拟机或加载系统资源等耗时操作

Zygote进程启动共做了如下几件事

  1. 创建AppRuntime并调用其start方法,启动Zygote进程
  2. 创建Java虚拟机并为Java虚拟机注册JNI方法
  3. 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层
  4. 通过registerZygoteSocket方法创建服务器端Socket,并通过runSelectLoop方法等待AMS的请求来创建新的应用程序进程
  5. 启动SystemServer进程

启动入口

在「init进程启动过程 - 解析与启动」笔记的最后,谈到了Zygote进程启动了,接下来看下frameworks/base/cmds/app_process/app_main.cpp的main方法

class AppRuntime : public AndroidRuntime{
    ...
}

#if defined(__LP64__)
...
static const char ZYGOTE_NICE_NAME[] = "zygote64";
#else
...
static const char ZYGOTE_NICE_NAME[] = "zygote";
#endif

int main(int argc, char* const argv[]){
    ...
	AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    ...
    bool zygote = false;
    bool startSystemServer = false;
    ...
    while (i < argc) {
        const char* arg = argv[i++];
        if (strcmp(arg, "--zygote") == 0) {
            //1 如果当前运行在Zygote进程中,则将zygote设置为true
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            //如果当前运行在SystemServer进程中,则将startSystemServer设置为true
            startSystemServer = true;
        } ...
    }
    
    ...
    if (zygote) {
        //2 如果运行在Zygote进程中
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } ...
}
  • 注释1:为什么要判断当前运行的进程是不是Zygote进程呢?因为Zygote是通过Fork来创建子进程的,由于Zygote进程和子进程共享同一份代码空间,所以子进程的代码也是有可能执行到while(i < argc){...}处的,所以这里要做一个判断
  • 注释2:如果运行在Zygote进程,就调用AppRuntime的start方法,该方法的实现在它的父类AndroidRuntime中

Native->Java

# classname:com.android.internal.os.ZygoteInit
# args
# zygote:true
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){
	...
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);       
    JNIEnv* env;    
    //1.启动Java虚拟机
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }    
    
    onVmCreated(env);
    //2.为Java虚拟机注册JNI方法
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
    
    ...
    //3.将className的"."替换为"/"    
    char* slashClassName = toSlashClassName(className);
    //4.找到ZygoteInit的Class
    jclass startClass = env->FindClass(slashClassName);
    
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);        
    } else {
        //5.找到ZygoteInit的main方法
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
        } else {
            //6.通过JNI调用ZygoteInit的main方法
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
            ...
        }
    }
}
  • 注释6:为什么这里要使用JNI呢?因为ZygoteInit的main方法是由Java编写的,当前的运行逻辑在Native中,这时候需要通过JNI来调用Java。这样Zygote从Native层进入了Java框架层,此前是没有任何代码进入Java框架层的,换句话说是Zygote开创了Java框架层

ZygoteInit的main方法

public static void main(String argv[]) {
    ZygoteServer zygoteServer = new ZygoteServer();
    ...
    try {
        ...
        //1.创建一个Server端的Socket,socketName的值为"zygote"    
        zygoteServer.registerServerSocket(socketName);
        if (!enableLazyPreload) {
        	...
            //2.预加载类和资源    
            preload(bootTimingsTraceLog);
            ...
        }
        ...
        if (startSystemServer) {
            //3.启动SystemServer进程
            startSystemServer(abiList, socketName, zygoteServer);
        }
        
        Log.i(TAG, "Accepting command socket connections");
        //4.等待AMS请求创建新的应用程序进程
        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;
    }    
}

ZygoteInit的main方法主要做了4件事情

  • 创建一个Server端的Socket
  • 预加载类和资源
  • 启动SystemServer进程
  • 等待AMS请求创建新的应用程序进程

这里"预加载类和资源"的部分不进行分析,"启动SystemServer进程"后面会分析

1.创建一个Server端的Socket

frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

    void registerServerSocket(String socketName) {
        if (mServerSocket == null) {
            int fileDesc;
            //拼接Socket的名称
            final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
            try {
                //得到Socket的环境变量的值
                String env = System.getenv(fullSocketName);
                //将Socket环境变量的值转换为文件描述符的参数
                fileDesc = Integer.parseInt(env);
            } catch (RuntimeException ex) {
                throw new RuntimeException(fullSocketName + " unset or invalid", ex);
            }

            try {
                //创建文件描述符
                FileDescriptor fd = new FileDescriptor();
                fd.setInt$(fileDesc);
                //创建服务端SOcket
                mServerSocket = new LocalServerSocket(fd);
            } catch (IOException ex) {
                throw new RuntimeException(
                        "Error binding to local socket '" + fileDesc + "'", ex);
            }
        }
    }
  • 这里拼接Socket的名称时,ANDROID_SOCKET_PREFIX的值为"ANDROID_SOCKET_",所以fullSocketName的值为"ANDROID_SOCKET_zygote"

3.启动SystemServer进程

后面分析~~

4.等待AMS请求创建新的应用程序进程

frameworks/base/core/java/com/android/internal/os/ZygoteServer.java

    void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
		//将前面创建的mServerSocket的文件描述符添加到列表fds中
        fds.add(mServerSocket.getFileDescriptor());
        //peers添加一个null,使得初始的时候fds和peers的size都为1
        peers.add(null);

        while (true) {
            //通过遍历将fds的信息转移到pollFds数组中
            StructPollfd[] pollFds = new StructPollfd[fds.size()];
            for (int i = 0; i < pollFds.length; ++i) {
                pollFds[i] = new StructPollfd();
                pollFds[i].fd = fds.get(i);
                pollFds[i].events = (short) POLLIN;
            }
            try {
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }
            for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                if (i == 0) {
                    /*
                    * i==0的时候,说明当前fds里面只有mServerSocker的文件描述符,说明此时
                    * 没有"创建应用程序进程"的请求,通过acceptCommandPeer方法等待连接
                    */
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                    /*
                    * i不等于0,说明这是一个"创建应用程序进程"的请求,通过调用ZygoteConnection
                    * 的runOnce方法,来创建一个"新的应用程序进程"
                    */
                    boolean done = peers.get(i).runOnce(this);
                    if (done) {
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
    }

这里等待"创建应用程序进程"的请求,是在无限循环while(true){...}里面实现的,一个可能的执行顺序如下

  1. 当前没有"创建应用程序进程"的请求,那么pollFds的length为1,则for循环里面的i等于0,那么会调用acceptCommandPeer方法
   /**
     * Waits for and accepts a single command connection. Throws
     * RuntimeException on failure.
     */
    private ZygoteConnection acceptCommandPeer(String abiList) {
        try {
            return createNewConnection(mServerSocket.accept(), abiList);
        } catch (IOException ex) {
            throw new RuntimeException(
                    "IOException during accept()", ex);
        }
    }

从方法的注释可以知道,此时会阻塞等待一个连接到来

  1. 当有一个连接请求到来时,会向fdspeers增加对应的元素,此时程序继续往下走,for循环结束,又进入while语句,这时for (int i = pollFds.length - 1; i >= 0; --i) {...},pollFds.length的值为2,也就是说,i的值先是1,那么就会走到下面的else语句,调用ZygoteConnectionrunOnce方法,来创建一个"新的应用程序进程",然后在fdspeers移除相应的元素,接着进入下一层的for循环,这时i的值为0,又是等待连接的到来,重复之前的步骤

这个runSelectLoop里面的执行顺序是自己的理解,不知道对不对

SystemServer进程启动过程

SystemServer进程主要用于创建系统服务,我们熟知的AMS、WMS和PMS都是由它来创建的

SystemServer进程被创建后,主要做了如下工作

  1. 启动Binder线程池,这样就可以与其他进程进行通信
  2. 创建SystemServiceManager,其用于对系统的服务进行创建、启动和生命周期管理
  3. 启动各种系统服务

前面谈到在Zygote进程中,会启动SystemServer进程,也就是在ZygoteInitmain方法的第三步,再放一下ZygoteInitmain方法

public static void main(String argv[]) {
    ZygoteServer zygoteServer = new ZygoteServer();
    ...
    try {
        ...
        //1.创建一个Server端的Socket,socketName的值为"zygote"    
        zygoteServer.registerServerSocket(socketName);
        if (!enableLazyPreload) {
        	...
            //2.预加载类和资源    
            preload(bootTimingsTraceLog);
            ...
        }
        ...
        if (startSystemServer) {
            //3.启动SystemServer进程
            startSystemServer(abiList, socketName, zygoteServer);
        }
        
        Log.i(TAG, "Accepting command socket connections");
        //4.等待AMS请求创建新的应用程序进程
        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;
    }    
}

进程启动

ZygoteInitstartSystemServer的实现如下

    private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
            throws Zygote.MethodAndArgsCaller, RuntimeException {
        ...
        //1.args数组用于保存SystemServer的启动参数
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            ...
            "--nice-name=system_server",
            "--runtime-args",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            //2.将args数组封转为ZygoteConnection.Arguments对象,供后面Fork进程的时候使用
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            //3.Fork进程
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /*
        * 4.Fork出来的SystemServer进程的pid==0,会执行下面的If语句,而Zygote进程不会执行下面
        *   的If语句
        */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }
			//5.关闭Zygote进程创建的Socket
            zygoteServer.closeServerSocket();
            handleSystemServerProcess(parsedArgs);
        }

        return true;
    }
  • 第3步:Zygote.forkSystemServer,内部会调用Native方法nativeForkSystemServer,该方法最终会通过fork函数,在当前进程(Zygote进程)创建一个子进程(SystemServer进程)

  • 第5步:SystemServer进程由Zygote进程Fork而来,所以SystemServer进程也复制了Zygote进程的地址空间,因此也会得到Zygote进程创建的mServerSocket,但是该Socket对于SystemServer进程没有用处,所以在注释5处,将其关闭

接着看下ZygoteInithandleSystemServerProcess

   private static void handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs)
            throws Zygote.MethodAndArgsCaller {
       ...
       if (parsedArgs.invokeWith != null) {
       	   ...
       } else {
           ClassLoader cl = null;
           if (systemServerClasspath != null) {
               //创建PathClassLoader
               cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);

               Thread.currentThread().setContextClassLoader(cl);
           }

           //调用zygoteInit方法,并且传入parsedArgs的剩余参数
           ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
       }       
   }
  • parseArgs:前面提到,这是SystemServer的启动参数的包装

ZygoteInitzygoteInit

    public static final void zygoteInit(int targetSdkVersion, String[] argv,
            ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
        ...
        //1.启动Binder线程池
        ZygoteInit.nativeZygoteInit();
        //2.进入SystemServer的main方法
        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
    }
  • 第1步:这里会通过JNI的方式,调用Native层的代码,最终通过Native层的AppRuntime,启动Binder线程池

抛出异常-清理栈帧

接着看RuntimeInitapplicationInit

	protected static void applicationInit(int targetSdkVersion, String[] argv,  
        	 ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
    	...
        invokeStaticMain(args.startClass, args.startArgs, classLoader);    
    }

RuntimeInitinvokeStaticMain

    # className:SystemServer
    # classLoader:前面创建的PathClassLoader
	private static void invokeStaticMain(String className, String[] argv, ClassLoader 
        classLoader) throws Zygote.MethodAndArgsCaller {
		Class<?> cl;

        try {
            cl = Class.forName(className, true, classLoader);
        } ...

        Method m;
        try {
            m = cl.getMethod("main", new Class[] { String[].class });
        } ...


        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
        throw new Zygote.MethodAndArgsCaller(m, argv);
    }

这段代码很有意思,首先是通过Class.forName,找到SystemServer对应的Class对象,接着通过反射,获取SystemServermain方法,然后将该方法包装到异常MethodAndArgsCaller中,将其抛出,MethodAndArgs Caller定义如下

    public static class MethodAndArgsCaller extends Exception
            implements Runnable {
        /** method to call */
        private final Method mMethod;

        /** argument array */
        private final String[] mArgs;

        public MethodAndArgsCaller(Method method, String[] args) {
            mMethod = method;
            mArgs = args;
        }

        public void run() {
            try {
                mMethod.invoke(null, new Object[] { mArgs });
            } ...
        }
    }

抛出的MethodAndArgsCaller会在前面提到的ZygoteInitmain方法中捕获到

public static void main(String argv[]) {
    ZygoteServer zygoteServer = new ZygoteServer();
    ...
    try {
        ...
        if (startSystemServer) {
            //3.启动SystemServer进程
            startSystemServer(abiList, socketName, zygoteServer);
        }
        
        Log.i(TAG, "Accepting command socket connections");
        //4.等待AMS请求创建新的应用程序进程
        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;
    }    
}
  • 为什么SystemServer进程的异常可以抛到这里呢?因为SystemServer进程由Zygote进程Fork而来,两个进程进程共享同一代码空间

  • caller.run():这里会执行MethodAndArgsCallerrun方法,通过反射调用到了SysetmServermain方法

    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        } ...
    }

那么,现在有一个问题,为什么不直接在RuntimeInitinvokeStaticMain里调用SystemServermain方法,而是这么大费周章呢?原因是这种抛出异常的处理会清除所有的设置过程需要的堆栈帧,让SystemServermain方法看起来像是SystemServer进程的入口方法一样,而实际上,在调用SystemServermain方法之前,已经做了很多的准备工作.

好NB的一个操作!!太秀了!

启动系统服务

接着看SystemServermain方法

   public static void main(String[] args) {
        new SystemServer().run();
    }

SystemServerrun

    private void run() {
        try {
            ...
            //创建消息Looper    
            Looper.prepareMainLooper();

            // 加载动态库libandroid_servers.so
            System.loadLibrary("android_servers");
            performPendingShutdown();
			//创建系统的Context
            createSystemContext();
			//创建SystemServiceManager
            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");
            //启动引导服务
            startBootstrapServices();
            //启动核心服务
            startCoreServices();
            //启动其他服务
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            ...
        } finally {
            traceEnd();
        }
        ...
    }
  • SystemServiceManager:会对系统服务进行创建、启动和生命周期管理
  • 官方把系统服务分为三种类型:引导服务、核心服务、其他服务

Launcher启动过程

系统启动的最后一步是启动Launcher应用程序,它用来显示系统中已安装的应用程序。SystemServer在启动系统服务的时候,会先启动AMS,然后会启动PackageManagerServicePackageManagerService启动后会将系统中的应用程序安装完成,AMS会在上面提到的startOtherServices方法中启动LauncherLauncher启动过程中会向PackageManagerService请求系统中已安装的应用程序的信息

Launcher作用有两点

  1. 作为Android系统的启动器,用于启动应用程序
  2. 作为Android系统的桌面,用于显示和管理应用程序的快捷图标或者其他桌面组件

启动过程

Launcher启动的部分时序图如下

Android系统启动_2

在时序图之后,还有下面的几步

  • 在调用完AMSstartHomeActivityLocked后,AMS会调用ActivityStarterstartHomeActivityLocked
  • startHomeActivityLocked方法中,会将Launcher放入ActivityStackSupervisorHomeStack变量中
  • 接着ActivityStarter调用自身的startActivityLocked方法来启动Launcher
  • 剩余的过程和Activity的启动过程类似,最终进入LauncheronCreate方法中,Launcher就完成了启动

应用图标显示过程

应用图标的显示过程可以分为以下几步

  1. LauncheronCreate中,获取LauncherAppState的实例,通过LauncherAppState的实例,获取到LauncherModel对象的引用,该LauncherModel持有Launcher的弱引用
  2. LauncheronCreate中,调用LauncherModelstartLoader方法
  3. 插入:在LauncherModel中,有一个静态变量HandlerThread sWorkerThread和一个静态变量Handler sWorkersWorker可以向sWorkerThread发送消息,让任务执行在子线程中
  4. LauncherModelstartLoader方法中,会构建一个对象LoaderTaskLoaderTask实现了Runnable接口,通过sWorkerLoaderTask代表的任务推送到子线程中去执行

LoaderTask是LauncherModel的内部类,定义如下

private class LoaderTask implements Runnable {...}
  1. LoaderTask的任务是"加载工作区信息"和"绑定工作区信息",接着会调用loadAllApps方法
  2. loadAllApps方法中,会通过主线程的Handler,将一个Runnable任务推送到主线程中执行,这个任务中,会调用LauncherbindAllApplications方法
  3. bindAllApplications方法中,会把"应用列表的信息"传给AllAppsContainerView mAppsViewAllAppsContainerView实际上是RelativeLayout的子类,它会保存"应用列表的信息",等到mAppsViewonFinishInflate方法被调用的时候,mAppsView会通过findViewById找到它内部的AllAppsRecyclerView,这实际上是RecyclerView的一个子类,通过为它设置设配器、"应用列表的信息"等,应用程序快捷图标的列表就会显示在屏幕上

onFinishInflate是View的方法

步骤就是这样,具体的过程可以看书~~

参考

《安卓进阶解密》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值