【Android】【Framework】进程的启动过程

进程的启动过程(AOSP4.4.2)

一、Zygote的启动过程

1------8

init.c init.rc app_process.cpp AndroidRuntime.cpp ZygoteInit main 创建zygote进程,执行main start main registerZygoteSocket startSystemServer runSelectLoop init.c init.rc app_process.cpp AndroidRuntime.cpp ZygoteInit

1. init.c : main
  • 分析和运行所有的 init.rc 文件
  • 生成设备驱动节点(通过 rc 文件创建)
  • 处理子进程的终止(signal方式)
  • 提供属性服务
c 复制代码
//aosp/system/core/init/init.c
int main(int argc, char **argv)
{
    ......
	/* 1.初始化kernel log */
    klog_init();
    /* 2.创建一块共享的内存空间,用于属性服务 */
    property_init();

    get_hardware_name(hardware, &revision);

    process_kernel_cmdline();

    union selinux_callback cb;
    cb.func_log = klog_write;
    selinux_set_callback(SELINUX_CB_LOG, cb);

    cb.func_audit = audit_callback;
    selinux_set_callback(SELINUX_CB_AUDIT, cb);

    selinux_initialize();
    /* These directories were necessarily created before initial policy load
     * and therefore need their security context restored to the proper value.
     * This must happen before /dev is populated by ueventd.
     */
    restorecon("/dev");
    restorecon("/dev/socket");
    restorecon("/dev/__properties__");
    restorecon_recursive("/sys");

    is_charger = !strcmp(bootmode, "charger");

    INFO("property init\n");
    /* 3.加载/default.prop文件 */
    if (!is_charger)
        property_load_boot_defaults();

    INFO("reading config file\n");
    /* 4.解析init.rc文件 */
    init_parse_config_file("/init.rc");

    /* 5.执行rc文件中触发器为on early-init的语句 */
    action_for_each_trigger("early-init", action_add_queue_tail);

    queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");
    queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
    queue_builtin_action(keychord_init_action, "keychord_init");
    queue_builtin_action(console_init_action, "console_init");

    // 使我们开始执行所有的引导操作
    /* 5.执行rc文件中触发器为on init的语句 */
    action_for_each_trigger("init", action_add_queue_tail);

    // 跳过在charger模式下挂载文件系统
    if (!is_charger) {
        action_for_each_trigger("early-fs", action_add_queue_tail);
        action_for_each_trigger("fs", action_add_queue_tail);
        action_for_each_trigger("post-fs", action_add_queue_tail);
        action_for_each_trigger("post-fs-data", action_add_queue_tail);
    }

    /* Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
     * wasn't ready immediately after wait_for_coldboot_done
     */
    queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");

    queue_builtin_action(property_service_init_action, "property_service_init");
    queue_builtin_action(signal_init_action, "signal_init");
    queue_builtin_action(check_startup_action, "check_startup");

    if (is_charger) {
        action_for_each_trigger("charger", action_add_queue_tail);
    } else {
        action_for_each_trigger("early-boot", action_add_queue_tail);
        action_for_each_trigger("boot", action_add_queue_tail);
    }

    // 基于属性的当前状态运行所有属性触发器
    queue_builtin_action(queue_property_triggers_action, "queue_property_triggers");


#if BOOTCHART
    queue_builtin_action(bootchart_init_action, "bootchart_init");
#endif

    for(;;) {
        int nr, i, timeout = -1;

        execute_one_command();
        restart_processes();

        if (!property_set_fd_init && get_property_set_fd() > 0) {
            ufds[fd_count].fd = get_property_set_fd();
            ufds[fd_count].events = POLLIN;
            ufds[fd_count].revents = 0;
            fd_count++;
            property_set_fd_init = 1;
        }
        if (!signal_fd_init && get_signal_fd() > 0) {
            ufds[fd_count].fd = get_signal_fd();
            ufds[fd_count].events = POLLIN;
            ufds[fd_count].revents = 0;
            fd_count++;
            signal_fd_init = 1;
        }
        if (!keychord_fd_init && get_keychord_fd() > 0) {
            ufds[fd_count].fd = get_keychord_fd();
            ufds[fd_count].events = POLLIN;
            ufds[fd_count].revents = 0;
            fd_count++;
            keychord_fd_init = 1;
        }

        if (process_needs_restart) {
            timeout = (process_needs_restart - gettime()) * 1000;
            if (timeout < 0)
                timeout = 0;
        }

        if (!action_queue_empty() || cur_action)
            timeout = 0;

#if BOOTCHART
        if (bootchart_count > 0) {
            if (timeout < 0 || timeout > BOOTCHART_POLLING_MS)
                timeout = BOOTCHART_POLLING_MS;
            if (bootchart_step() < 0 || --bootchart_count == 0) {
                bootchart_finish();
                bootchart_count = 0;
            }
        }
#endif

        nr = poll(ufds, fd_count, timeout);
        if (nr <= 0)
            continue;

        for (i = 0; i < fd_count; i++) {
            if (ufds[i].revents == POLLIN) {
                if (ufds[i].fd == get_property_set_fd())
                    handle_property_set_fd();
                else if (ufds[i].fd == get_keychord_fd())
                    handle_keychord();
                else if (ufds[i].fd == get_signal_fd())
                    handle_signal();
            }
        }
    }

    return 0;
}
2. init.rc
  • service:告诉 init 进程创建一个名为 "zygote" 的进程,这个 zygote 进程要执行的程序是 /system/bin/app_process ,后面是要传给 app_process 的参数
  • --start-system-server:表示当 Zygote 进程启动完成后,马上将 System 进程也启动
  • socket:表示在 Zygote 启动的过程中,要在内部创建一个名称为 "zygote" 的 Socket 资源,用来进行 IPC,所用用户都可以对它进行读写。系统启动后,就可以在 /dev/socket 目录下看到一个名为 zygote 的文件
  • onrestart:表示这个 zygote 进程重启时需要执行的命令
  • 由此得知, Zygote 进程要执行的程序是 system/bin/app_process
shell 复制代码
#system/core/rootdir/init.rc
......
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
......
3. app_process.cpp : main
  • 调用 AndroidRuntime 的 start 函数
c++ 复制代码
//frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
	......
    /* 1.这个函数的主要作用就是创建一个AppRuntime变量,
    接下来的Zygote进程就是通过它进一步启动的 */
    AppRuntime runtime;
    const char* argv0 = argv[0];

    // Process command line arguments
    // ignore argv[0]
    argc--;
    argv++;

    // Everything up to '--' or first non '-' arg goes to the vm
    int i = runtime.addVmArguments(argc, argv);

    // 解析运行时参数。停止在第一个未识别的选项
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    const char* parentDir = NULL;
    const char* niceName = NULL;
    const char* className = NULL;
    while (i < argc) {
        const char* arg = argv[i++];
        if (!parentDir) {
            parentDir = arg;
         /* 2.检查是否包含一个--zygote选项,如果包含,就说明
         这时候应用程序app_process是在Zygote进程中启动的 */
        } else if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            /* 3.设置当前进程名称为zygote */
            niceName = "zygote";
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } ......
    }

    if (niceName && *niceName) {
        setArgv0(argv0, niceName);
        set_process_name(niceName);
    }

    runtime.mParentDir = parentDir;

    if (zygote) {
        /* 4.然后调用它的start成员函数。这里的参数
        startSystemServer为true,表示要启动SystemServer
        组件。由于AppRuntime没有实现自己的start函数,它
        继承了父类AndroidRuntime的start函数,因此会执行
        AndroidRuntime类的start函数 */
        runtime.start("com.android.internal.os.ZygoteInit",
                startSystemServer ? "start-system-server" : "", 
                      zygote);
    } else if (className) {
        // 其余的参数被传递给启动类main()
        runtime.mClassName = className;
        runtime.mArgC = argc - i;
        runtime.mArgV = argv + i;
        runtime.start("com.android.internal.os.RuntimeInit",
                application ? "application" : "tool", zygote);
    } else {
        fprintf(stderr, 
                "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG_ALWAYS_FATAL(
            "app_process: no class name or --zygote supplied.");
        return 10;
    }
}
3.1 AppRuntime
  • 继承于 AndroidRuntime 类

  • 当 AppRuntime 对象创建时,调用其父类 AndroidRuntime 的构造函数

c++ 复制代码
//frameworks/base/cmds/app_process/app_main.cpp
namespace android {
	class AppRuntime : public AndroidRuntime
    {
    	......
    };
}
3.2 AndroidRuntime
  • 在 AndroidRuntime 类的构造函数里,会将 this 指针保存在静态全局变量 gCurRuntime 中
c++ 复制代码
//frameworks/base/core/jni/AndroidRuntime.cpp
......
static AndroidRuntime* gCurRuntime = NULL;
......
AndroidRuntime::AndroidRuntime() :
        mExitWithoutCleanup(false)
{
    ......
	assert(gCurRuntime == NULL);        // one per process
    gCurRuntime = this;
}
  • 当其它地方需要使用这个 AppRuntime 对象时,就可以通过同一个文件中的这个函数,来获取这个对象的指针:
c++ 复制代码
AndroidRuntime* AndroidRuntime::getRuntime()
{
    return gCurRuntime;
}
4. AndroidRuntime.cpp : start
  • 作用是启动 Android 系统运行时库
c++ 复制代码
//frameworks/base/core/jni/AndroidRuntime.cpp
void AndroidRuntime::start(const char* className, const char* options, bool zygote)
{
    ......
    if (strcmp(options, "start-system-server") == 0) {
        // 通过引导顺序跟踪我们的进度
        const int LOG_BOOT_PROGRESS_START = 3000;
        ......
    }
    const char* rootDir = getenv("ANDROID_ROOT");
    if (rootDir == NULL) {
        rootDir = "/system";
        if (!hasDir("/system")) {
            ......
            return;
        }
        setenv("ANDROID_ROOT", rootDir, 1);
    }
    ......

    // 启动虚拟机
    JniInvocation jni_invocation;
    jni_invocation.Init(NULL);
    JNIEnv* env;
    
    /* 1.调用函数startVM启动虚拟机 */
    if (startVm(&mJavaVM, &env, zygote) != 0) {
        return;
    }
    onVmCreated(env);

    /* 2.调用函数startReg注册JNI方法 */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }
    ......
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;
    jstring optionsStr;

    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    strArray = env->NewObjectArray(2, stringClass, NULL);
    assert(strArray != NULL);
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);
    optionsStr = env->NewStringUTF(options);
    env->SetObjectArrayElement(strArray, 1, optionsStr);

    // 启动虚拟机。该线程成为VM的主线程,直到VM退出才返回
    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ......
    } else {
        /* 3.调用了com.android.internal.os.ZygoteInit类的
        main函数 */
        jmethodID startMeth = env->GetStaticMethodID(
            startClass, "main", "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
             ......
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, 
                                      strArray);
 			......
        }
    }
    free(slashClassName);
    ......
}
5. ZygoteInit.main
java 复制代码
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
    ......
	public static void main(String argv[]) {
        try {
            ......
            /* 1.创建了一个Server端的Socket,用来等待AMS请求Zygote
            进程创建新的应用程序进程 */
            registerZygoteSocket();
            ......
            if (argv[1].equals("start-system-server")) {
                /* 2.启动SystemServer组件,它可以启动系统的关键
                服务 */
                startSystemServer();
            } else if (!argv[1].equals("")) {
                ......
            }
            ......
            /* 3.进入一个无限循环,在前面创建的Socket上等待AMS请求
            创建新的应用程序进程 */
            runSelectLoop();
            closeServerSocket();
        } catch (MethodAndArgsCaller caller) {
            caller.run();
        } catch (RuntimeException ex) {
            ......
            closeServerSocket();
            throw ex;
        }
    }
	......
}
6. ZygoteInit.registerZygoteSocket
java 复制代码
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
    ......
    private static final String ANDROID_SOCKET_ENV = 
        "ANDROID_SOCKET_zygote";
    ......
   	private static void registerZygoteSocket() {
        if (sServerSocket == null) {
            int fileDesc;
            try {
                /* 1.文件描述符通过环境变量ANDROID_SOCKET_ENV得到*/ 
                String env = System.getenv(ANDROID_SOCKET_ENV);
                fileDesc = Integer.parseInt(env);
            } ......
            try {
                /* 2.这个socket接口是通过文件描述符来创建的,
                这个文件描符代表的就是前面说的
                /dev/socket/zygote文件 */
                sServerSocket = new LocalServerSocket(
                        createFileDescriptor(fileDesc));
            } ......
        }
    }
    ......
}
6.1 环境变量ANDROID_SOCKET_ENV的设置如下
  • init.c : service_start
c 复制代码
//system/core/init/init.c
......
void service_start(struct service *svc, const char *dynamic_args)
{
    ......
    pid_t pid;
    ......
    /* 1.每一个service命令都会使init进程调用fork函数来创建一
    个新的进程 */
    pid = fork();
    if (pid == 0) {
        struct socketinfo *si;
        ......
        /* 2.在新的进程里面,会分析里面的socket选项 */
        for (si = svc->sockets; si; si = si->next) {
            int socket_type = (
                    !strcmp(si->type, "stream") ? SOCK_STREAM :
                        (!strcmp(si->type, "dgram") ? 
                         SOCK_DGRAM : 
                         SOCK_SEQPACKET));
            /* 3.对于每一个socket选项,都会通过create_socket
            函数来在/dev/socket目录下创建一个文件,在这个场景
            中,这个文件便是zygote了 */
            int s = create_socket(si->name, socket_type,
                                  si->perm, si->uid, si->gid);
            if (s >= 0) {
                /* 4.然后得到的文件描述符通过publish_socket
                函数写入到环境变量中去 */
                publish_socket(si->name, s);
            }
        }
        ......
    }
    ......
}
......
  • init.c:publish_socket
    • 把上面得到的文件描述符写入到以 "ANDROID_SOCKET_zygote" 为 key 值的环境变量中
    • 因为上面的 ZygoteInit.registerZygoteSocket 函数与这里创建 socket 文件的 create_socket 函数是运行在同一个进程中,因此,上面的 ZygoteInit.registerZygoteSocket 函数可以直接使用这个文件描述符来创建一个 Java 层的 LocalServerSocket 对象
    • 如果其它进程需要打开这个 /dev/socket/zygote 文件来和 Zygote 进程进行通信,那就必须要通过文件名来连接这个 LocalServerSocket
c 复制代码
//system/core/init/init.c
......
/* 1.这里传进来的参数name值为"zygote" */
static void publish_socket(const char *name, int fd)
{
    /* 2.ANDROID_SOCKET_ENV_PREFIX在system/core/include/cutils/sockets.h定义 */
    char key[64] = ANDROID_SOCKET_ENV_PREFIX;
    char val[64];

    strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1,
            name,
            sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX));
    snprintf(val, sizeof(val), "%d", fd);
    add_environment(key, val);

    /* make sure we don't close-on-exec */
    fcntl(fd, F_SETFD, 0);
}
......

ANDROID_SOCKET_ENV_PREFIX 的定义:

c 复制代码
//system/core/include/cutils/sockets.h
......
#define ANDROID_SOCKET_ENV_PREFIX	"ANDROID_SOCKET_"
......
7. ZygoteInit.startSystemServer
java 复制代码
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
    ......
	private static boolean startSystemServer()
            throws MethodAndArgsCaller, RuntimeException {
        long capabilities = posixCapabilitiesAsBits(
            OsConstants.CAP_KILL,
            OsConstants.CAP_NET_ADMIN,
            OsConstants.CAP_NET_BIND_SERVICE,
            OsConstants.CAP_NET_BROADCAST,
            OsConstants.CAP_NET_RAW,
            OsConstants.CAP_SYS_MODULE,
            OsConstants.CAP_SYS_NICE,
            OsConstants.CAP_SYS_RESOURCE,
            OsConstants.CAP_SYS_TIME,
            OsConstants.CAP_SYS_TTY_CONFIG,
            OsConstants.CAP_BLOCK_SUSPEND
        );
        /* 1.保存System进程的启动参数 */
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,
                1018,1032,3001,3002,3003,3006,3007",
            "--capabilities=" + capabilities + "," + capabilities,
            "--runtime-init",
            "--nice-name=system_server",
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;
        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(
                parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(
                parsedArgs);

            // 请求fork系统服务器进程
            /* 2.Zygote进程创建一个新的进程,这个进程就是Android的
            System进程 */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.debugFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } ......

        // 对于子进程
        /* 3.返回值pid等0的地方就是新的进程要执行的路径,即新
        创建的进程会执行下面的函数。 */
        if (pid == 0) {
            handleSystemServerProcess(parsedArgs);
        }
        return true;
    }
    ......
}
8. ZygoteInit.runSelectLoop
  • 等待 AMS 来连接这个 Socket ,然后调用 ZygoteConnection.runOnce 函数来创建新的应用程序
java 复制代码
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
    ......
	private static void runSelectLoop() 
        throws MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = 
            new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = 
            new ArrayList<ZygoteConnection>();
        /* 1.创建一个大小为4的Socket文件描述符数组,表示Zygote
        最多能同时有4个连接 */
        FileDescriptor[] fdArray = new FileDescriptor[4];
        /* 2.将ZygoteInit类的静态成员变量sServerSocket所描述
        的一个Socket的文件描述符添加到Socket文件描述符fds列表
        中,它是socket通信中的服务端 */
        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);

        int loopCount = GC_LOOP_COUNT;
        /* 3.该无限循环用来等AMS请求Zygote进程创建新的应用
        程序进程 */
        while (true) {
            int index;
            ......
            if (loopCount <= 0) {
                gc();
                loopCount = GC_LOOP_COUNT;
            } else {
                loopCount--;
            }

            try {
                /* 4.首先将保存在Socket文件描述符列表fds中的Socket
                文件描述符转移到Socket文件描述符数组fdArray中 */
                fdArray = fds.toArray(fdArray);
                /* 5.调用selectReadable来监控保存在这个数组中的
                Socket是否有数据可读,当一个Socket有数据可读意味
                着它接收到了一个连接或者一个请求 */
                index = selectReadable(fdArray);
            } ......
			
            if (index < 0) {
                ......
            } else if (index == 0) {
                /* 6.如果index为0,那么说明AMS通过ZygoteInit
                类的静态成员变量sServerSocket所描述的一个Socket
                与Zygote进程建立了新的连接。将这个连接添加到
                Socket连接列表peers,将用来描述这个连接的一个
                Socket文件描述符添加到Socket文件描述符列表fds,
                以便接下来接受AMS发送的创建应用程序的请求 */
                ZygoteConnection newPeer = acceptCommandPeer();
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            } else {
                /* 7.如果index为大于0,AMS则向Zygote进程发送
                了一个创建应用程序进程的请求。因此就会调用前面
                已经建立起来的一个连接(ZygoteConnection)的
                成员函数runOnce创建一个新的应用程序进程 */
                boolean done;
                done = peers.get(index).runOnce();
				
                /* 8.将这个连接删除,因为此时Zygote已处理完
                这个连接 */
                if (done) {
                    peers.remove(index);
                    fds.remove(index);
                }
            }
        }
    }
    ......
}

二、SystemServer的启动过程

  • 服务启动的通常流程:
    • 实例化服务
    • 调用 ServiceManager.addService 将服务添加到 ServiceManager 中
    • 调用服务的 systemReady() 方法
1------9

ZygoteInit RuntimeInit MethodAndArgsCaller SystemServer ServerThread startSystemServer handleSystemServerProcess zygoteInit nativeZygoteInit applicationInit invokeStaticMain 抛出异常 run 反射:main initAndLoop ZygoteInit RuntimeInit MethodAndArgsCaller SystemServer ServerThread

1. ZygoteInit.handleSystemServerProcess
java 复制代码
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
    ......
	private static void handleSystemServerProcess(
            ZygoteConnection.Arguments parsedArgs)
            throws ZygoteInit.MethodAndArgsCaller {
		/* 1.由于System进程复制了Zygote进程的地址空间,因此,
		它会获得Zygote进程启动过程中创建的Socket。System进程
		不需要这个Socket,所以为关闭它 */
        closeServerSocket();
        ......
        if (parsedArgs.invokeWith != null) {
            WrapperInit.execApplication(
                parsedArgs.invokeWith, parsedArgs.niceName, 
                parsedArgs.targetSdkVersion, null, 
                parsedArgs.remainingArgs);
        } else {
            // 将剩余的参数传递给 SystemServer
            /* 2.调用RuntimeInit.zygoteInit函数来进一步执行启动
            SystemServer组件的操作 */
            RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, 
                                   parsedArgs.remainingArgs);
        }
    }
    ......
}
2. RuntimeInit.zygoteInit
java 复制代码
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public class RuntimeInit {
    ......
	public static final void zygoteInit(
        int targetSdkVersion, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        ......
        redirectLogStreams();
		/* 1.设置System进程的时区和键盘布局等通用信息 */
        commonInit();
        /* 2.zygote初始化,在System进程中启动一个Binder线程池 */
        nativeZygoteInit();

        applicationInit(targetSdkVersion, argv);
    }
    ......
}
3. RuntimeInit.nativeZygoteInit
java 复制代码
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public class RuntimeInit {
    ......
    private static final native void nativeZygoteInit();
    ......
}
4. RuntimeInit.applicationInit
java 复制代码
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public class RuntimeInit {
    ......
    private static void applicationInit(
        int targetSdkVersion, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        ......
        nativeSetExitWithoutCleanup(true);

        // 我们希望在堆利用方面相当积极,以避免保留大量不需要的内存。
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetSdkVersion(
            targetSdkVersion);

        final Arguments args;
        try {
            args = new Arguments(argv);
        } ......

        // Remaining arguments are passed to the start class's static main
        invokeStaticMain(args.startClass, args.startArgs);
    }
    ......
}
5. RuntimeInit.invokeStaticMain
java 复制代码
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public class RuntimeInit {
    ......
    private static void invokeStaticMain(
        String className, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;
        try {
            cl = Class.forName(className);
        } ......
            
        Method m;
        try {
            m = cl.getMethod("main", 
                             new Class[] { String[].class });
        } ......
            
        int modifiers = m.getModifiers();
        if (! (Modifier.isStatic(modifiers) 
               && Modifier.isPublic(modifiers))) {
            ......
        }
        ......
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }
    ......
}
6. ZygoteInit.main
java 复制代码
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
    ......
	public static void main(String argv[]) {
        try {
            ......
        } catch (MethodAndArgsCaller caller) {
            /* 1.捕捉到MethodAndArgsCaller异常后,就会调用run */
            caller.run();
        } ......
    }
	......
}
7. MethodAndArgsCaller.run
java 复制代码
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
    ......
	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 });
            } ......
        }
    }
    ......
}
8. SystemServer.main
java 复制代码
//frameworks/base/services/java/com/android/server/SystemServer.java
public class SystemServer {
    ......
	public static void main(String[] args) {
        ......
        Slog.i(TAG, "Entered the Android system server!");

        // 初始化本地服务。
        nativeInit();

		/* 1.创建一个ServerThread线程,将它启动起来 */
        ServerThread thr = new ServerThread();
        thr.initAndLoop();
    }
}
9. ServerThread.initAndLoop
  • 初始化各个服务
  • 通过 ServiceManager.addService 方法将服务添加到 ServiceManager ,通过 Binder IPC 访问这些服务
java 复制代码
//frameworks/base/services/java/com/android/server/SystemServer.java
class ServerThread {
	......
	public void initAndLoop() {
        ......
        /* 1.创建一个消息循环 */
        Looper.prepareMainLooper();
        ......
        /* 2.启动系统的关键服务,并且将它们注册到
        Service Manager中 */
        try {
            ......
            Slog.i(TAG, "Activity Manager");
            context = ActivityManagerService.main(factoryTest);
        } ......

        ......

        try {
            ......
            Slog.i(TAG, "Package Manager");
            ......
            pm = PackageManagerService.main(context, installer,
                    factoryTest != SystemServer.FACTORY_TEST_OFF, onlyCore);
            ......
            ActivityManagerService.setSystemProcess();
            ......
            Slog.i(TAG, "Content Manager");
            contentService = ContentService.main(
                context, factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);
            ......
            Slog.i(TAG, "Window Manager");
            wm = WindowManagerService.main(
                context, power, display, inputManager, wmHandler, 
                factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
                    !firstBoot, onlyCore);
            ServiceManager.addService(Context.WINDOW_SERVICE, wm);
            ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
            ......
        } ......
            
        ......
            
        /* 3.使当前线程进入到一个消息循环中,在Android中,
        每一个线程都可以有一个 */
		Looper.loop();
        Slog.d(TAG, "System ServerThread is exiting!");
    }
   	......
}
10------14

ServerThread Looper PowerManagerService prepareMainLooper PowerManagerService AMS.main DisplayManagerService PKMS.main AMS.setSystemProcess ContentService.main LightsService BatteryService init LightsService InputManagerService WMS.main BluetoothManagerService InputMethodManagerService MountService ServerThread Looper PowerManagerService
ServerThread NetworkStatsService NetworkPolicyManagerService WifiP2pService WifiService NetworkManagementService.create NetworkStatsService NetworkPolicyManagerService WifiP2pService WifiService ConnectivityService bindConnectivityManager bindConnectivityManager connectivityServiceReady checkAndStartWifi ServerThread NetworkStatsService NetworkPolicyManagerService WifiP2pService WifiService
ServerThread Looper DreamManagerService loop ServerThread Looper

10. AMS.main
java 复制代码
//frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    ......
    static ActivityManagerService mSelf;
    ......
	public static final Context main(int factoryTest) {
        AThread thr = new AThread();
        thr.start();

        synchronized (thr) {
            while (thr.mService == null) {
                try {
                    thr.wait();
                } ......
            }
        }

        ActivityManagerService m = thr.mService;
        mSelf = m;
        ......
    }
    
    ......
        
    static class AThread extends Thread {
        ActivityManagerService mService;
        Looper mLooper;
        ......
        @Override
        public void run() {
            Looper.prepare();
            ......
            ActivityManagerService m = new ActivityManagerService();

            synchronized (this) {
                mService = m;
                mLooper = Looper.myLooper();
                ......
                notifyAll();
            }
            ......
            Looper.loop();
        }
    }
    ......
}
11. PKMS.main
java 复制代码
//frameworks/base/services/java/com/android/server/pm/PackageManagerService.java
public class PackageManagerService extends IPackageManager.Stub {
    ......
	public static final IPackageManager main(
        Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        /* 1.创建一个PMS实例,管理系统的package */
        PackageManagerService m = new PackageManagerService(context, installer,
                factoryTest, onlyCore);
        /* 2.注册到Service Manager中,并且指定它的名称为
        "package" */
        ServiceManager.addService("package", m);
        return m;
    }
    ......
}
12. AMS.setSystemProcess
  • frameworks/base/core/java/android/content/Context.java:public static final String ACTIVITY_SERVICE = "activity";
java 复制代码
//frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    ......
    public static void setSystemProcess() {
        try {
            ActivityManagerService m = mSelf;
			/* 1.注册到Service Manager中的名称为
			Context.ACTIVITY_SERVICE,其他进程可以通过该名
			称获取他的一个Binder代理对象,从而访问它提供的服务 */
            ServiceManager.addService(Context.ACTIVITY_SERVICE, m, true);
            ......
        } ......
    }
    ......
}
13. ContentService.main
java 复制代码
//frameworks/base/services/java/com/android/server/content/ContentService.java
public final class ContentService extends IContentService.Stub {
    ......
    public static ContentService main(Context context, boolean factoryTest) {
        /* 1.创建一个ContentService实例,作为系统的Content
        管理服务 */
        ContentService service = new ContentService(context, factoryTest);
        /* 2.接着将它注册到Service Manager中,指定其名称为
        ContentResolver.CONTENT_SERVICE_NAME */
        ServiceManager.addService(ContentResolver.CONTENT_SERVICE_NAME, service);
        return service;
    }
    ......
}
14. WMS.main
java 复制代码
//frameworks/base/services/java/com/android/server/wm/WindowManagerService.java
public class WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs,
                DisplayManagerService.WindowManagerFuncs, 
				DisplayManager.DisplayListener {
	......
    public static WindowManagerService main(
        final Context context, final PowerManagerService pm, 
        final DisplayManagerService dm,
        final InputManagerService im, final Handler wmHandler,
        final boolean haveInputMethods, final boolean showBootMsgs,
            final boolean onlyCore) {
        final WindowManagerService[] holder = new WindowManagerService[1];
        wmHandler.runWithScissors(new Runnable() {
            @Override
            public void run() {
                holder[0] = new WindowManagerService(
                    context, pm, dm, im, haveInputMethods, showBootMsgs, onlyCore);
            }
        }, 0);
        return holder[0];
    }
    ......
}

三、ActivityThread的启动过程

  • Android Framework 层创建的应用程序进程具有两个特点:

    • 进程的入口函数是 ActivityThread.main
    • 进程天然支持 Binder IPC 机制
  • 入口函数是 ActivityThread.main:即进程创建完成后,Android Framework 层会在这个进程中将 ActivityThread 类加载进来,执行它的 main 函数,这个 main 函数就是进程执行消息循环的地方

  • 天然支持 Binder IPC 机制:Android 应用程序进程在创建的时候,就已经启动了一个线程池来支持 Server 组件和 Binder 驱动程序之间的通信

  • 应用进程在启动的过程中,可以获得一个虚拟机实例、一个 Binder 线程池和一个消息循环

1------8:应用程序进程的创建过程

AMS Process ZygoteInit ZygoteConnection RuntimeInit startProcessLocked start startViaZygote zygoteSendArgsAndGetResult 侦听Socket:runSelectLoop runOnce handleChildProc zygoteInit AMS Process ZygoteInit ZygoteConnection RuntimeInit

1. AMS.startProcessLocked
  • 当 AMS 需要创建一个新的应用程序进程,来启动一个应用程序组件时,它就会调用成员函数 startProcessLocked 向 Zygote 进程发送一个创建应用程序进程的请求
java 复制代码
//frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    ......
    private final void startProcessLocked(ProcessRecord app,
            String hostingType, String hostingNameStr) {
        ......
        try {
            /* 1.获取要创建的应用程序进程的用户ID以及用户组ID */
            int uid = app.uid;
            int[] gids = null;
            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
            if (!app.isolated) {
                int[] permGids = null;
                try {
                    final PackageManager pm = mContext.getPackageManager();
                    permGids = pm.getPackageGids(app.info.packageName);
                    ......
                } ......
                ......
            }
            ......
            int debugFlags = 0;
            ......
            /* 2.调用了Process.start函数开始为应用程序创建
            新的进程 */
            Process.ProcessStartResult startResult = Process.start(
                "android.app.ActivityThread", pp.processName, uid, uid, gids, debugFlags,
                mountExternal, app.info.targetSdkVersion, app.info.seinfo, null);
            ......
        } ......
    }
    ......
}
2. Process.start
java 复制代码
//frameworks/base/core/java/android/os/Process.java
public class Process {
    ......
    public static final ProcessStartResult start(
        final String processClass, final String niceName,
        int uid, int gid, int[] gids, int debugFlags, 
        int mountExternal, int targetSdkVersion,
        String seInfo, String[] zygoteArgs) {
        try {
            /* 1.调用函数请求Zygote进程创建一个应用程序进程 */
            return startViaZygote(processClass, niceName, uid, gid, gids,
                debugFlags, mountExternal, targetSdkVersion, seInfo, zygoteArgs);
        } ......
    }
    ......
}
3. Process.startViaZygote
java 复制代码
//frameworks/base/core/java/android/os/Process.java
public class Process {
    ......
	private static ProcessStartResult startViaZygote(
        final String processClass,
        final String niceName,
        final int uid, final int gid,
        final int[] gids,
        int debugFlags, int mountExternal,
        int targetSdkVersion,
        String seInfo,
        String[] extraArgs)
        throws ZygoteStartFailedEx {
        synchronized(Process.class) {
            /* 1.将创建进程的参数放到argsForZygote列表中去 */
            ArrayList<String> argsForZygote = new ArrayList<String>();

            // --runtime-init, --setuid=, --setgid=,
            // and --setgroups= must go first
            /* 2.--runtime-init表示在新创建的应用程序进程中
            初始化运行时库,以及启动一个Binder线程池 */
            argsForZygote.add("--runtime-init");
            argsForZygote.add("--setuid=" + uid);
            argsForZygote.add("--setgid=" + gid);
			......
            // --setgroups is a comma-separated list
            if (gids != null && gids.length > 0) {
                StringBuilder sb = new StringBuilder();
                sb.append("--setgroups=");
                int sz = gids.length;
                for (int i = 0; i < sz; i++) {
                    if (i != 0) {
                        sb.append(',');
                    }
                    sb.append(gids[i]);
                }
                argsForZygote.add(sb.toString());
            }

            if (niceName != null) {
                argsForZygote.add("--nice-name=" + niceName);
            }

            if (seInfo != null) {
                argsForZygote.add("--seinfo=" + seInfo);
            }

            argsForZygote.add(processClass);

            if (extraArgs != null) {
                for (String arg : extraArgs) {
                    argsForZygote.add(arg);
                }
            }
			/* 3.调用zygoteSendAndGetPid函数进一步操作 */
            return zygoteSendArgsAndGetResult(argsForZygote);
        }
    }
    ......
}
4. Process.zygoteSendArgsAndGetResult
java 复制代码
//frameworks/base/core/java/android/os/Process.java
public class Process {
    ......
    private static final String ZYGOTE_SOCKET = "zygote";
	......
    // 用来与Zygote进程中一个名称为"zygote"的Socket建立连接。
    // Zygote进程在启动时,会在内部创建一个名称为"zygote"的
    // Socket,这个Socket与设备文件/dev/socket/zygote绑定
    // 在一起。
    static LocalSocket sZygoteSocket;
    static DataInputStream sZygoteInputStream;
    static BufferedWriter sZygoteWriter;

    /** true if previous zygote open failed */
    static boolean sPreviousZygoteOpenFailed;
    ......
    private static void openZygoteSocketIfNeeded() throws ZygoteStartFailedEx {
        int retryCount;
        if (sPreviousZygoteOpenFailed) {
            ......
            retryCount = 0;
        } else {
            retryCount = 10;            
        }
        ......
        for (int retry = 0; (sZygoteSocket == null) && (retry < (retryCount + 1)); 
             retry++ ) {
            if (retry > 0) {
                try {
                    Log.i("Zygote", "Zygote not up yet, 
                          sleeping...");
                    Thread.sleep(ZYGOTE_RETRY_MILLIS);
                } ......
            }
            try {
                /* 2.创建一个LocalSocket对象 */
                sZygoteSocket = new LocalSocket();
                /* 3.将sZygoteSocket与名称为ZYGOTE_SOCKET的
                Socket地址建立连接。在连接的过程中,
                sZygoteSocket会在/dev/socket目录下找到一个对
                应的zygote文件,然后和其进行绑定 */
                sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET, 
                        LocalSocketAddress.Namespace.RESERVED));
				
                /* 4.获取一个输入流,以便获取Zygote进程发送
                过来的通信数据 */
                sZygoteInputStream = new DataInputStream(sZygoteSocket.getInputStream());
                /* 5.获取一个输出流,便可以向Zygote进程发送通
                信数据 */
                sZygoteWriter = new BufferedWriter(new OutputStreamWriter(
                    sZygoteSocket.getOutputStream()), 256);
                Log.i("Zygote", "Process: zygote socket opened");
                sPreviousZygoteOpenFailed = false;
                break;
            } ......
        }
        ......
    }
    
	private static ProcessStartResult zygoteSendArgsAndGetResult(ArrayList<String> args)
            throws ZygoteStartFailedEx {
        /* 1.创建一个连接到Zygote进程的LocalSocket对象 */
        openZygoteSocketIfNeeded();

        try {
            ......
            /* 6.将要创建的应用程序进程的启动参数列表写入
            到这个LocalSocket对象中,以便将它们传递给Zygote
            进程。Zygote收到这些数据后,就会创建一个新的应用
            程序进程,并将这个新的应用程序进程的PID返回给AMS */
            sZygoteWriter.write(Integer.toString(args.size()));
            sZygoteWriter.newLine();
            for (int i = 0; i < sz; i++) {
                String arg = args.get(i);
                sZygoteWriter.write(arg);
                sZygoteWriter.newLine();
            }
            sZygoteWriter.flush();

            // Should there be a timeout on this?
            ProcessStartResult result = new ProcessStartResult();
            ......
            result.pid = sZygoteInputStream.readInt();
            result.usingWrapper = sZygoteInputStream.readBoolean();

            if (result.pid < 0) {
                throw new ZygoteStartFailedEx("fork() failed");
            }
            return result;
        } ......
    }
	......
}
5. ZygoteInit.runSelectLoop
  • 侦听上面的 Socket
java 复制代码
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
    ......
	private static void runSelectLoop() throws MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
        FileDescriptor[] fdArray = new FileDescriptor[4];

        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);

        int loopCount = GC_LOOP_COUNT;
        while (true) {
            int index;
			......
            try {
                fdArray = fds.toArray(fdArray);
                index = selectReadable(fdArray);
            } ......

            if (index < 0) {
                throw new RuntimeException("Error in select()");
            } else if (index == 0) {
                ZygoteConnection newPeer = acceptCommandPeer();
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            } else {
                boolean done;
                /* 1.上面将数据通过Socket接口发送出去后,就会
                执行下面这个语句 */
                /* 2.peers.get(index)得到的是一个ZygoteConnection对象,
                表示一个Socket连接,因此,接下来就是调用ZygoteConnection.runOnce
                函数进一步处理了 */
                done = peers.get(index).runOnce();
                if (done) {
                    peers.remove(index);
                    fds.remove(index);
                }
            }
        }
    }
    ......
}
6. ZygoteConnection.runOnce
java 复制代码
//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
class ZygoteConnection {
    ......
	boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
        String args[];
        Arguments parsedArgs = null;
        FileDescriptor[] descriptors;

        try {
            /* 1.获得将要创建的应用程序进程的启动参数 */
            args = readArgumentList();
            descriptors = mSocket.getAncillaryFileDescriptors();
        } ......
        ......
        /** the stderr of the most recent request, if avail */
        PrintStream newStderr = null;

        if (descriptors != null && descriptors.length >= 3) {
            newStderr = new PrintStream(new FileOutputStream(descriptors[2]));
        }

        int pid = -1;
        FileDescriptor childPipeFd = null;
        FileDescriptor serverPipeFd = null;

        try {
            parsedArgs = new Arguments(args);
            ......
            /* 2.真正创建进程的地方就是在这里了。这个函数会创建
            一个进程,而且有两个返回值,一个是在当前进程中返回的,
            一个是在新创建的进程中返回,即在当前进程的子进程中返
            回,在当前进程中的返回值就是新创建的子进程的pid值,
            而在子进程中的返回值是0 */
            pid = Zygote.forkAndSpecialize(
                parsedArgs.uid, parsedArgs.gid, 
                parsedArgs.gids, parsedArgs.debugFlags, 
                rlimits, parsedArgs.mountExternal, 
                parsedArgs.seInfo, parsedArgs.niceName);
        } ......

        try {
            if (pid == 0) {
                ......
                /* 3.调用 */
                handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

                // should never get here, the child is expected to either
                // throw ZygoteInit.MethodAndArgsCaller or exec().
                return true;
            } ......
        } ......
    }
    ......
}
7. ZygoteConnection.handleChildProc
java 复制代码
//frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
class ZygoteConnection {
    ......
	private void handleChildProc(Arguments parsedArgs,
            FileDescriptor[] descriptors, FileDescriptor pipeFd, 
                                 PrintStream newStderr)
            throws ZygoteInit.MethodAndArgsCaller {
        ......
        /* 1.前面的3中,指定了"--runtime-init"参数,表示要为新创建的进
        程初始化运行时库,因此,这里的parseArgs.runtimeInit值为true */
        if (parsedArgs.runtimeInit) {
            if (parsedArgs.invokeWith != null) {
                WrapperInit.execApplication(parsedArgs.invokeWith,
                        parsedArgs.niceName, parsedArgs.targetSdkVersion,
                        pipeFd, parsedArgs.remainingArgs);
            } else {
                /* 2.于是继续执行RuntimeInit.zygoteInit进一步处理 */
                RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
                        parsedArgs.remainingArgs);
            }
        } ......
    }
    ......
}
8. RuntimeInit.zygoteInit
java 复制代码
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public class RuntimeInit {
    ......
    private static final native void nativeZygoteInit();
    ......
	public static final void zygoteInit(int targetSdkVersion, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        ......
        redirectLogStreams();
        commonInit();
        /* 1.执行Binder驱动程序初始化的相关工作,由于执行了这个工作,才使
        得进程中的Binder对象能够顺利地进行Binder进程间通信 */
        nativeZygoteInit();
        applicationInit(targetSdkVersion, argv);
    }
    ......
    private static void applicationInit(int targetSdkVersion, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        ......
        nativeSetExitWithoutCleanup(true);
        ......
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

        final Arguments args;
        try {
            args = new Arguments(argv);
        } ......

        /* 2.执行进程的入口函数,这里就是执行startClass类的main函数了,
        而这个startClass即是我们在Step 1中传进的
        "android.app.ActivityThread"值,表示要执行
        android.app.ActivityThread类的main函数。 */
        invokeStaticMain(args.startClass, args.startArgs);
    }

    public static void redirectLogStreams() {
        System.out.close();
        System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
        System.err.close();
        System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
    }
    ......
}
9:Binder线程池的启动过程

RuntimeInit nativeZygoteInit RuntimeInit

9. RuntimeInit.nativeZygoteInit
10------14:消息循环的创建过程

RuntimeInit ZygoteInit MethodAndArgsCaller ActivityThread applicationInit invokeStaticMain 捕捉异常main run 反射main RuntimeInit ZygoteInit MethodAndArgsCaller ActivityThread

10. RuntimeInit.applicationInit
java 复制代码
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public class RuntimeInit {
    ......
    private static void applicationInit(int targetSdkVersion, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        ......
        nativeSetExitWithoutCleanup(true);

        // 我们希望在堆利用方面相当积极,以避免保留大量不需要的内存。
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

        final Arguments args;
        try {
            args = new Arguments(argv);
        } ......

        // Remaining arguments are passed to the start class's static main
        invokeStaticMain(args.startClass, args.startArgs);
    }
    ......
}
11. RuntimeInit.invokeStaticMain
java 复制代码
//frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
public class RuntimeInit {
    ......
    private static void invokeStaticMain(String className, String[] argv)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;
        try {
            /* 1.前面说过,这里传进来的参数className字符串值
            为"android.app.ActivityThread",这里就将它加载到进程中 */
            cl = Class.forName(className);
        } ......
        
        Method m;
        try {
            /* 2.然后获得它的静态成员函数main */
            m = cl.getMethod("main", new Class[] { String[].class });
        } ......
            
        int modifiers = m.getModifiers();
        ......
        /* 3.函数最后并没有直接调用这个静态成员函数main,而是通过抛出一个
        异常ZygoteInit.MethodAndArgsCaller,然后让ZygoteInit.main函
        数在捕获这个异常的时候再调用android.app.ActivityThread类的main
        函数。
        原因:它是为了清理堆栈的,这样就会让android.app.ActivityThread
        类的main函数觉得自己是进程的入口函数,这样打印的堆栈信息看起来会比较
        清爽~ */
        throw new ZygoteInit.MethodAndArgsCaller(m, argv);
    }
    ......
}
12. ZygoteInit.main
java 复制代码
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
    ......
	public static void main(String argv[]) {
        try {
            ......
        } catch (MethodAndArgsCaller caller) {
            /* 1.捕捉到MethodAndArgsCaller异常后,就会调用run */
            caller.run();
        } ......
    }
	......
}
13. MethodAndArgsCaller.run
java 复制代码
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public class ZygoteInit {
    ......
	public static class MethodAndArgsCaller extends Exception
            implements Runnable {
        /** method to call */
        /* 指向了ActivityThread类的静态成员函数main */
        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 });
            } ......
        }
    }
    ......
}
14. ActivityThread.main
  • 以后可以在这个进程中启动 Activity 或 Service
java 复制代码
//frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread {
    ......
	public static void main(String[] args) {
        SamplingProfilerIntegration.start();
        ......
        Looper.prepareMainLooper();
        /* 1.首先会在进程中创建一个ActivityThread对象 */
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        ......
        /* 2.然后进入消息循环中 */
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
}

四、Launcher的启动过程分析

  1. Android 系统的 Home 应用程序 Launcher 是由 AMS 启动的,而 AMS 和 PKMS 一样,都是在开机时由 SystemServer 启动的
  2. SystemServer 首先是启动 PKMS ,由它来负责安装系统的应用程序;SystemServer 接下来通过 AMS 来启动 Launcher
  3. Launcher 在启动的时候会通过 PKMS 把系统中已安装好的 APP ,以快捷图标的形式展示在桌面上
1------9:AMS 的世界

SystemServer ServerThread AMS ASS ActivityStack nativeInit initAndLoop systemReady resumeTopActivitiesLocked_1 resumeTopActivitiesLocked_2 resumeTopActivityLocked_1 resumeTopActivityLocked_2 resumeHomeActivity startHomeActivityLocked startHomeActivity SystemServer ServerThread AMS ASS ActivityStack

1. SystemServer.main
  • SystemServer 组件由 Zygote 进程负责启动,启动时会调用它的 main 函数,该函数调用了 Native 方法做系统初始化
java 复制代码
//frameworks/base/services/java/com/android/server/SystemServer.java
public class SystemServer{
	......
	public static void main(String[] args) {
        ......
        Slog.i(TAG, "Entered the Android system server!");

        // Initialize native services.
        nativeInit();
        /* 1.新建一个ServerThread线程,AMS服务就是在这个线程中启动 */
		ServerThread thr = new ServerThread();
		/* 2.里调用initAndLoop */
        thr.initAndLoop();
	}
	......
}
2. SystemServer.nativeInit
3. ServerThread.initAndLoop
  • 启动 AMS 服务
  • 启动 PKMS 服务
  • 系统中的一系列服务都在初始化完毕后调用 systemReady
java 复制代码
//frameworks/base/services/java/com/android/server/SystemServer.java
class ServerThread {
    ......
	public void initAndLoop() {
        ......
        String factoryTestStr = SystemProperties.get("ro.factorytest");
        int factoryTest = "".equals(factoryTestStr) ?
            SystemServer.FACTORY_TEST_OFF : Integer.parseInt(factoryTestStr);
        ......
        try {
            ......
            Slog.i(TAG, "Activity Manager");
            context = ActivityManagerService.main(factoryTest);
        } ......
		......
        try {
            ......
            Slog.i(TAG, "Package Manager");
            ......
            pm = PackageManagerService.main(context, installer,
                    factoryTest != SystemServer.FACTORY_TEST_OFF,
                    onlyCore);
            ......
        } ......
        ......
        ActivityManagerService.self().systemReady(
            ......
        );
        ......
        Looper.loop();
    }
    ......
}
4. AMS.systemReady
  • mStackSupervisor 是一个 ActivityStackSupervisor 类型的实例变量,它是用来管理所有系统堆栈的
java 复制代码
//frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
   	......
    public void systemReady(final Runnable goingCallback) {
        ......
        synchronized (this) {
            ......
            /* 1.启动Home应用程序 */
            mStackSupervisor.resumeTopActivitiesLocked();
            ......
        }
    }
    ......
}
5. ActivityStackSupervisor.resumeTopActivitiesLocked
java 复制代码
//frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java
public final class ActivityStackSupervisor {
    ......
    //All the non-launcher stacks
    private ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
    ......
	boolean resumeTopActivitiesLocked() {
        return resumeTopActivitiesLocked(null, null, null);
    }
    boolean resumeTopActivitiesLocked(ActivityStack targetStack, 
             			ActivityRecord target,Bundle targetOptions) {
        if (targetStack == null) {
            targetStack = getFocusedStack();
        }
        boolean result = false;
        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
            /* 1.获取栈顶的ActivityStack */
            final ActivityStack stack = mStacks.get(stackNdx);
            if (isFrontStack(stack)) {
                if (stack == targetStack) {
                    /* 2.通过ActivityStack类型的变量stack调用 
                    resumeTopActivityLocked */
                    result = stack.resumeTopActivityLocked(target, targetOptions);
                } else {
                    stack.resumeTopActivityLocked(null);
                }
            }
        }
        return result;
    }
    ......
}
6. ActivityStack.resumeTopActivityLocked
java 复制代码
//frameworks/base/services/java/com/android/server/am/ActivityStack.java
final class ActivityStack {
    ......
	final boolean resumeTopActivityLocked(ActivityRecord prev) {
        return resumeTopActivityLocked(prev, null);
    }

    final boolean resumeTopActivityLocked(
        ActivityRecord prev, Bundle options) {
        ......
        // Find the first activity that is not finishing.
        /* 1.调用函数topRunningActivityLocked返回当前系统
        Activity堆栈最顶端的Activity,由于此时还没有Activity
        被启动过,因此,返回值为null,即next变量的值为null */
        ActivityRecord next = topRunningActivityLocked(null);
		......
        if (next == null) {
            // There are no more activities!  Let's just start up the
            // Launcher...
            ActivityOptions.abort(options);
            ......
            if (DEBUG_STACK) mStackSupervisor.
                validateTopActivitiesLocked();
            /* 2.这里的mStackSupervisor是前面在AMS中创建的
            ActivityStackSupervisor实例 */
            return mStackSupervisor.resumeHomeActivity(prev);
        }
		......
    }
    ......
}
7. ActivityStackSupervisor.resumeHomeActivity
java 复制代码
//frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java
public final class ActivityStackSupervisor {
    ......
    final ActivityManagerService mService;
    ......
	boolean resumeHomeActivity(ActivityRecord prev) {
                moveHomeToTop();
        if (prev != null) {
            prev.task.mOnTopOfHome = false;
        }
        ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
        if (r != null && r.isHomeActivity()) {
            mService.setFocusedActivityLocked(r);
            return resumeTopActivitiesLocked(mHomeStack, prev, null);
        }
        return mService.startHomeActivityLocked(mCurrentUser);
    }
    ......
}
8. ⭐AMS.startHomeActivityLocked
java 复制代码
//frameworks/base/services/java/com/android/server/am/ActivityManagerService.java
public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    ......
    Intent getHomeIntent() {
        ⭐⭐⭐⭐⭐
        /* 1.修改该Intent */
        Intent intent = new Intent(
            mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
        intent.setComponent(mTopComponent);
        if (mFactoryTest != SystemServer.
            FACTORY_TEST_LOW_LEVEL) {
            intent.addCategory(Intent.CATEGORY_HOME);
        }
        return intent;
    }

    boolean startHomeActivityLocked(int userId) {
        ......
        /* 1.函数首先调用getHomeIntent函数创建一个
        CATEGORY_HOME类型的Intent */
        Intent intent = getHomeIntent();
        /* 2.向PKMS查询Intent的ActivityInfo */
        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.instrumentationClass == null) {
                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                mStackSupervisor.startHomeActivity(intent, aInfo);
            }
        }
        return true;
    }
    ......
}
9. ActivityStackSupervisor.startHomeActivity
  • 具体过程看:Activity的启动
  • 在这里,调用这个函数的最后结果就是把 com.android.launcher2.Launcher 启动起来,接着调用它的 onCreate 函数
java 复制代码
//frameworks/base/services/java/com/android/server/am/ActivityStackSupervisor.java
public final class ActivityStackSupervisor {
	......
	void startHomeActivity(Intent intent, ActivityInfo aInfo) {
        moveHomeToTop();
        startActivityLocked(
            null, intent, null, aInfo, null, null, 0, 0, 0, null, 0, null, false, null);
    }
	......
	final int startActivityLocked(IApplicationThread caller,
            Intent intent, String resolvedType, 
            ActivityInfo aInfo, IBinder resultTo,
            String resultWho, int requestCode,
            int callingPid, int callingUid, 
            String callingPackage, int startFlags, 
            Bundle options,boolean componentSpecified, 
            ActivityRecord[] outActivity) {
        int err = ActivityManager.START_SUCCESS;

        ProcessRecord callerApp = null;
        if (caller != null) {
            /* 1.从传进来的参数caller得到调用者的进程信息,并保存在
            callerApp变量中,这里就是Launcher应用程序的进程信息 */
            callerApp = mService.getRecordForAppLocked(caller);
            if (callerApp != null) {
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } ......
        }
        ......
        ActivityRecord sourceRecord = null;
        ActivityRecord resultRecord = null;
        if (resultTo != null) {
            /* 2.参数resultTo是Launcher这个Activity里面的一个
            Binder对象,通过它可以获得Launcher这个Activity的
            相关信息,保存在sourceRecord变量中 */
            sourceRecord = isInAnyStackLocked(resultTo);
            ......
            if (sourceRecord != null) {
                if (requestCode >= 0 && !sourceRecord.finishing) {
                    resultRecord = sourceRecord;
                }
            }
        }
        ActivityStack resultStack = resultRecord == null ? null : 
        resultRecord.task.stack;

        int launchFlags = intent.getFlags();

        if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
                && sourceRecord != null) {
            // Transfer the result target from the source activity to the new
            // one being started, including any failures.
            if (requestCode >= 0) {
                ActivityOptions.abort(options);
                return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
            }
            resultRecord = sourceRecord.resultTo;
            resultWho = sourceRecord.resultWho;
            requestCode = sourceRecord.requestCode;
            sourceRecord.resultTo = null;
            if (resultRecord != null) {
                resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
            }
        }

        if (err == ActivityManager.START_SUCCESS && 
            intent.getComponent() == null) {
            ......
        }

        if (err == ActivityManager.START_SUCCESS && 
            aInfo == null) {
            ......
        }

        if (err != ActivityManager.START_SUCCESS) {
            ......
        }
        ......
        ActivityRecord r = new ActivityRecord(
            mService, callerApp, callingUid, callingPackage,
            intent, resolvedType, aInfo, mService.mConfiguration,
            resultRecord, resultWho, requestCode, 
            componentSpecified, this);
        ......
        err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
        ......
        return err;
    }
    ......
}
10------20:Launcher的世界

ASS Launcher LauncherModel LoaderTask PKMS AppsCustomizePagedView onCreate startLoader run loadAndBindAllApps loadAllAppsByBatch queryIntentActivities bindAllApplications setApps ASS Launcher LauncherModel LoaderTask PKMS AppsCustomizePagedView

10. Launcher.onCreate
java 复制代码
//packages/apps/Launcher2/src/com/android/launcher2/Launcher.java
public final class Launcher extends Activity
        implements View.OnClickListener, OnLongClickListener, 
					LauncherModel.Callbacks, View.OnTouchListener {
    ......
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ......
        if (!mRestoring) {
            if (sPausedFromUserAction) {
                // 如果用户离开启动器,那么我们应该在它们返回时
                // 异步加载项目。
                /* 1.这里的mModel是一个LauncherModel类型的
                成员变量 */
                mModel.startLoader(true, -1);
            } else {
                // 如果用户在启动器处于前台时旋转
                //(或触发配置更改),只会同步加载页面
                /* 2.调用它的startLoader成员函数来执行加载
                应用程序的操作 */
                mModel.startLoader(true, 
                                   mWorkspace.getCurrentPage());
            }
        }
        ......
    }
    ......
}
11. LauncherModel.startLoader
  • 这里不是直接加载应用程序,而是把加载应用程序的操作作为一个消息处理
  • 这里的 sWorker 是一个 Handler ,通过它的 post 方式把一个消息放在消息队列中去,然后系统就会调用传进去的参数 mLoaderTask 的 run 函数来处理这个消息
  • 这个 mLoaderTask 是 LoaderTask 类型的实例,于是,下面就会执行 LoaderTask 类的 run 函数
java 复制代码
//packages/apps/Launcher2/src/com/android/launcher2/LauncherModel.java
public class LauncherModel extends BroadcastReceiver {
    ......
    public void startLoader(boolean isLaunching, int synchronousBindPage) {
        synchronized (mLock) {
            ......
            // 如果我们知道它不会做任何事情,就不要费心去启动线程
            if (mCallbacks != null && mCallbacks.get() != null) {
                /* 如果已经有一个正在运行,告诉它停止。另外,
                如果我们已经在运行,不要降级isLaunching */
                isLaunching = isLaunching || stopLoaderLocked();
                mLoaderTask = new LoaderTask(mApp, isLaunching);
                if (synchronousBindPage > -1 && mAllAppsLoaded
                    && mWorkspaceLoaded) {
                    mLoaderTask.runBindSynchronousPage(
                        synchronousBindPage);
                } else {
                    sWorkerThread.setPriority(
                        Thread.NORM_PRIORITY);
                    sWorker.post(mLoaderTask);
                }
            }
        }
    }
    ......
}
12. LauncherModel.LoaderTask.run
java 复制代码
//packages/apps/Launcher2/src/com/android/launcher2/LauncherModel.java
public class LauncherModel extends BroadcastReceiver {
    ......
    private class LoaderTask implements Runnable {
        ......
        public void run() {
            ......
            /* 优化最终用户体验:如果启动器已启动并在前台运行
            所有应用程序界面,请先加载所有应用程序。 否则,首先
            加载工作区(默认)*/
            final Callbacks cbk = mCallbacks.get();
            final boolean loadWorkspaceFirst = cbk != null ? 
            (!cbk.isAllAppsVisible()) : true;
            keep_running:
            {
                ......
                if (loadWorkspaceFirst) {
                    ......
                    loadAndBindWorkspace();
                } else {
                    ......
                    /* 1.调用loadAndBindAllApps函数 */
                    loadAndBindAllApps();
                }
                ......
            }
            ......
        }
        ......
    }
    ......
}
13. LauncherModel.LoaderTask.loadAndBindAllApps
  • 由于还没有加载过应用程序,这里的 mAllAppsLoaded 为 false
  • 于是就继续调用 loadAllAppsByBatch 函数来进一步操作
java 复制代码
//packages/apps/Launcher2/src/com/android/launcher2/LauncherModel.java
public class LauncherModel extends BroadcastReceiver {
    ......
    private class LoaderTask implements Runnable {
        ......
        private void loadAndBindAllApps() {
            ......
            /* 1.由于还没有加载过应用程序,这里的
            mAllAppsLoaded为false */
            if (!mAllAppsLoaded) {
                /* 2.于是就继续调用loadAllAppsByBatch
                函数来进一步操作了 */
                loadAllAppsByBatch();
                synchronized (LoaderTask.this) {
                    if (mStopped) {
                        return;
                    }
                    mAllAppsLoaded = true;
                }
            } else {
                onlyBindAllApps();
            }
        }
        ......
    }
    ......
}
14. LauncherModel.LoaderTask.loadAllAppsByBatch
java 复制代码
//packages/apps/Launcher2/src/com/android/launcher2/LauncherModel.java
public class LauncherModel extends BroadcastReceiver {
    ......
    private class LoaderTask implements Runnable {
        ......
        private void loadAllAppsByBatch() {
            ......
			
            /* 1.函数首先构造一个CATEGORY_LAUNCHER类型的Intent */
            final Intent mainIntent = 
                new Intent(Intent.ACTION_MAIN, null);
            mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
			
            /* 2.接着从mContext变量中获得PMS的接口 */
            final PackageManager packageManager = 
                mContext.getPackageManager();
            List<ResolveInfo>    apps           = null;

            int N = Integer.MAX_VALUE;

            int startIndex;
            int i         = 0;
            int batchSize = -1;
            while (i < N && !mStopped) {
                if (i == 0) {
                    mBgAllAppsList.clear();
                    ......
                    /* 3.下一步就是通过这个PMS的
                    queryIntentActivities接口来取
                    回所有Action类型为Intent.ACTION_MAIN,
                    并且Category类型为Intent.CATEGORY_LAUNCHER
                    的Activity */
                    apps = packageManager.queryIntentActivities(
                        mainIntent, 0);
                    ......
                    N = apps.size();
                    ......
                    if (mBatchSize == 0) {
                        batchSize = N;
                    } else {
                        batchSize = mBatchSize;
                    }

                    ......
                    Collections.sort(apps,
                            new LauncherModel.
                                     ShortcutNameComparator(
                                packageManager, mLabelCache));
                    ......
                }
                ......
                startIndex = i;
                for (int j = 0; i < N && j < batchSize; j++) {
                    // This builds the icon bitmaps.
                    mBgAllAppsList.add(
                        new ApplicationInfo(
                            packageManager, apps.get(i),
                            mIconCache, mLabelCache));
                    i++;
                }

                final boolean first = i <= batchSize;
                final Callbacks callbacks = 
                tryGetCallbacks(oldCallbacks);
                final ArrayList<ApplicationInfo> added = 
                    mBgAllAppsList.added;
                mBgAllAppsList.added = 
                    new ArrayList<ApplicationInfo>();

                mHandler.post(new Runnable() {
                    public void run() {
                        final long t = 
                            SystemClock.uptimeMillis();
                        if (callbacks != null) {
                            if (first) {
                                callbacks.
                                    bindAllApplications(added);
                            } else {
                                callbacks.bindAppsAdded(added);
                            }
                            ......
                        } ......
                    }
                });
                ......
            }
            ......
        }
        ......
    }
    ......
}
15. PKMS.queryIntentActivities
  • 系统在前面的 PKMS 启动到安装应用程序的过程: Step.8 中,启动 PKMS 时会把系统中的应用程序都解析一遍,然后把解析得到的 Activity 都保存在 mActivities 变量中
java 复制代码
//frameworks/base/services/java/com/android/server/pm/PackageManagerService.java
public class PackageManagerService extends IPackageManager.Stub {
    ......
    public List<ResolveInfo> queryIntentActivities(Intent intent,
            String resolvedType, int flags, int userId) {
        ......
        synchronized (mPackages) {
            final String pkgName = intent.getPackage();
            if (pkgName == null) {
                /* 1.这里通过这个mActivities变量的queryIntent
                函数返回符合条件intent的Activity */
				/* 2.这里要返回的便是Action类型为
				Intent.ACTION_MAIN,并且Category类型为
				Intent.CATEGORY_LAUNCHER的Activity */
                return mActivities.queryIntent(
                    intent, resolvedType, flags, userId);
            }
            ......
        }
    }
    ......
}
16. Launcher.bindAllApplications
java 复制代码
//packages/apps/Launcher2/src/com/android/launcher2/Launcher.java
public final class Launcher extends Activity
        implements View.OnClickListener, OnLongClickListener, 			
					LauncherModel.Callbacks, View.OnTouchListener {
    ......
    private AppsCustomizePagedView mAppsCustomizeContent;
    ......
    public void bindAllApplications(final ArrayList<ApplicationInfo> apps) {
        Runnable setAllAppsRunnable = new Runnable() {
            public void run() {
                if (mAppsCustomizeContent != null) {
                    mAppsCustomizeContent.setApps(apps);
                }
            }
        };
        // 完全移除进度条; 我们也可以让它消失,但最好删除它,
        // 因为我们知道它不会被使用
        View progressBar = mAppsCustomizeTabHost.
                findViewById(R.id.apps_customize_progress_bar);
        if (progressBar != null) {
            ((ViewGroup) progressBar.getParent()).removeView(progressBar);
            /* 我们只是发布对 setApps 的调用,以便用户看到进度
            条消失 - 否则,它看起来就像进度条冻结,看起来不太好 */
            mAppsCustomizeTabHost.post(setAllAppsRunnable);
        } else {
            /* 如果我们没有在 onCreate 中初始化 spinner,
            那么我们可以直接设置应用程序列表,而无需等待隐藏任何
            进度条视图 */
            setAllAppsRunnable.run();
        }
    }
    ......
}
17. AppsCustomizePagedView.setApps
java 复制代码
//packages/apps/Launcher2/src/com/android/launcher2//AppsCustomizePagedView.java
public class AppsCustomizePagedView extends PagedViewWithDraggableItems 
    implements View.OnClickListener, View.OnKeyListener, DragSource,
        PagedViewIcon.PressedCallback, PagedViewWidget.ShortPressListener,
        LauncherTransitionable {
    ......
    public void setApps(ArrayList<ApplicationInfo> list) {
        mApps = list;
        Collections.sort(mApps, LauncherModel.getAppNameComparator());
        updatePageCountsAndInvalidateData();
    }
    ......
    private void updatePageCountsAndInvalidateData() {
        if (mInBulkBind) {
            mNeedToUpdatePageCountsAndInvalidateData = true;
        } else {
            updatePageCounts();
            invalidateOnDataChange();
            mNeedToUpdatePageCountsAndInvalidateData = false;
        }
    }
    ......
    private void invalidateOnDataChange() {
        if (!isDataReady()) {
            /* 如果设置了小部件和应用程序,则下一个布局传递将触发
            数据就绪,因此请求布局以在就绪时触发页面数据 */
            requestLayout();
        } else {
            cancelAllTasks();
            invalidatePageData();
        }
    }
    private void updatePageCounts() {
        mNumWidgetPages = (int) Math.ceil(mWidgets.size() /
                (float) (mWidgetCountX * mWidgetCountY));
        mNumAppsPages = (int) Math.ceil((float) mApps.size() 
                                        / (mCellCountX * mCellCountY));
    }
    ......
}
相关推荐
用户2018792831678 小时前
Java经典一问:String s = new String("xxx");创建了几个String对象?
android
用户2018792831678 小时前
用 “建房子” 讲懂 Android 中 new 对象的全过程:从代码到 ART 的魔法
android
手机不死我是天子8 小时前
《Android 核心组件深度系列 · 第 4 篇 ContentProvider》
android·架构
鹏多多8 小时前
flutter-切换状态显示不同组件10种实现方案全解析
android·前端·ios
FengyunSky9 小时前
高通Camx内存问题排查
android·linux·后端
00后程序员张10 小时前
苹果软件混淆的工程逻辑,从符号空间到资源扰动的体系化实现
android·ios·小程序·https·uni-app·iphone·webview
alexhilton18 小时前
突破速度障碍:非阻塞启动画面如何将Android 应用启动时间缩短90%
android·kotlin·android jetpack
kobe_OKOK_18 小时前
Django `models.Field` 所有常见配置参数的完整清单与说明表
android
前行的小黑炭20 小时前
Android Compose :初步了解一下生命周期,对比原生android
android·kotlin·app