Android开发之漫漫长途 XI——从I到X的小结

该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽可能按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索》以及《深刻理解Android 卷Ⅰ,Ⅱ,Ⅲ》中的相关知识,另外也借鉴了其余的优质博客,在此向各位大神表示感谢,膜拜!!!另外,本系列文章知识可能须要有必定Android开发基础和项目经验的同窗才能更好理解,也就是说该系列文章面向的是Android中高级开发工程师。html


前言

上面十几篇文章咱们从Android的创世之初到了Activity显示以及View的绘制、事件体系,咱们也分析了Binder和Handler。读者是否是以为我这个系列要完了呀。那大家就大错特错了。介绍前面的知识咱们是为了后面的知识打底的。那么本篇文章呢,是对前面文章的一个总结。毕竟一会儿放出那么多东西,我怕大家的当心脏已经爆棚了。因此本篇文章咱们再梳理一下。java

注:前面文章咱们主要讲了和显示相关的知识如Activity、Window、View等android

注:如下源码来自android-6.0.0_r5c++

奇点——init进程

咱们在Android开发之漫漫长途 Ⅰ——Android系统的创世之初以及Activity的生命周期就提到了init进程,init也是Android系
统中用户空间的第一个进程,它的进程号是1。 做为天字第一号进
程,init进程负责建立系统中的几个关键进程,尤为是zygote,它更是Java世界的开创者。
关于进程的概念,我想读者们应该都很清楚了,不论咱们使用的是c语言仍是java语言,咱们在最初写HelloWordld程序的时候,咱们建立.cpp或者.java文件,关键的是在文件中定义入口方法main,咱们在main方法中打印出一行HelloWord,而后咱们编译运行该程序,咱们这个运行起来的程序就能够看作是一个进程。而咱们init进程也不例外,它是由c++编写的一个可执行程序,咱们很容易的就想到要先看其main方法。shell

[init.cpp]性能优化

int main(int argc, char** argv) {
    .....
    //解析init.rc文件
    init_parse_config_file("/init.rc");
    .....
    //执行各个阶段的动做,建立zygote的工做就是在其中的某个
阶段完成的
    action_for_each_trigger("early-init", action_add_queue_tail);

    .....
   
  
    action_for_each_trigger("init", action_add_queue_tail);

    .....
    //init进入一个无限循环,而且等待一些事情的发生
    while (true) {
        
    }

    return 0;
}

init进程的工做仍是挺繁重的,咱们精简以后获得上面三步:app

解析init.rc文件

init.rc文件的解析是init进程的重要工做,咱们的重要进程如SM进程、Zygote进程等都是解析该文件而后建立的。下面给出的节选自init.rc文件中的内容socket

[init.rc]ide

//导入其余配置文件

import /init.${ro.hardware}.rc
//看这个难道是导入zygote相关的配置文件吗??
import /init.${ro.zygote}.rc


on early-init
    # Set init and its forked children's oom_adj.
    write /proc/1/oom_score_adj -1000

    # Set the security context of /adb_keys if present.
    restorecon /adb_keys

    start ueventd

on init
    sysclktz 0

那么这个ro.zygote又是个什么鬼,其实它是定义在product_64_only.mk和core_minimal.mk中的,根据平台是32位仍是64位ro.zygote被赋值为zygote64或者zygote32函数

[init.zygote64.rc]

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

那么有了上面的文件以后,咱们是怎么解析上面的配置文件的呢,咱们在init.cpp中的init_parse_config_file函数就是完成这个功能的。咱们来稍微看一下这个函数

[init_parser.cpp]

int init_parse_config_file(const char* path) {
    .....
    std::string data;
    .....
    //读取文件,这个文件就是init.rc
    if (!read_file(path, &data)) {
        return -1;
    }
    .....
    //调用parse_config作真正的解析
    parse_config(path, data);
    .....
    return 0;
}

关于这个具体的解析过程很复杂,读者若是有兴趣能够自行参看《深刻理解Android 卷Ⅰ》第3章,咱们这里就不详细分析了,,由于要分析它至少须要两篇博客。

咱们知道zygote是在init.rc文件中定义,init进程经过解析该文件并fork出Android中Java世界的开创者zygote。

小结

init进程是奇点,那么奇点爆炸后获得了什么呢?看下图

咱们来分析zygote进程,至于ServiceManager进程咱们已经在
Android开发之漫漫长途 IX——完全掌握Binder中分析了,至于其余进程的启动咱们之后有机会再来一一分析。

zygote进程

zygote自己是一个Native的应用程序,与驱动、 内核等均无关
系。 根据第上面对init的介绍咱们能够知道,zygote是由init进程根
据init.rc文件中的配置项建立的。
咱们同样来看一下其main函数

int main(int argc, char* const argv[])
{
    //咱们参数图如上图,这个数据来自在init.zygote64.rc中设置的/system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    ......
    argc--;
    //忽略argv[0];
    argv++;

    ......
    int i;
    for (i = 0; i < argc; i++) {
        if (argv[i][0] != '-') {
            break;
        }
        if (argv[i][1] == '-' && argv[i][2] == 0) {
            ++i; // Skip --.
            break;
        }
        runtime.addOption(strdup(argv[i]));
    }
    ......
    unrecognized option.
    bool zygote = false;
    bool startSystemServer = false;
    bool application = false;
    String8 niceName;
    String8 className;
    //这时咱们的i指向了--zygote所在的索引
    ++i; 
    
    while (i < argc) {
        //取出值,,这里取出arg=--zygote,而后i++
        const char* arg = argv[i++];

        if (strcmp(arg, "--zygote") == 0) {//进入这个分支
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        } else if (strcmp(arg, "--start-system-server") == 0) {
            //第2次循环进入这个分支
            startSystemServer = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName.setTo(arg + 12);
        } else if (strncmp(arg, "--", 2) != 0) {
            className.setTo(arg);
            break;
        } else {
            --i;
            break;
        }
    }
    Vector<String8> args;
    if (!className.isEmpty()) {
       
        args.add(application ? String8("application") : String8("tool"));
        runtime.setClassNameAndArgs(className, argc - i, argv + i);
    } else {
       
        ......
        if (startSystemServer) {
            args.add(String8("start-system-server"));
        }

        char prop[PROP_VALUE_MAX];
        if (property_get(ABI_LIST_PROPERTY, prop, NULL) == 0) {
            LOG_ALWAYS_FATAL("app_process: Unable to determine ABI list from property %s.",
                ABI_LIST_PROPERTY);
            return 11;
        }

        String8 abiFlag("--abi-list=");
        abiFlag.append(prop);
        args.add(abiFlag);

       
        ......
    }
    /*由上面的操做咱们获得了
    *niceName=ZYGOTE_NICE_NAME;
    *zygote = true;
    *startSystemServer = true;
    *
    *args=["start-system-server","--abi-list="];
    *这里args第2个元素"--abi-list="这个字符串的后面内容是根据支持的abi来拼接的,可是目前咱们只有这2个元素是肯定的
    */
    
    if (!niceName.isEmpty()) {
        runtime.setArgv0(niceName.string());
        set_process_name(niceName.string());
    }

    if (zygote) {
        //调用Runtime.start方法
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } else if (className) {
        runtime.start("com.android.internal.os.RuntimeInit", args, 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;
    }
}

AppRuntime

上面咱们的代码走到了AppRuntime的start函数中,咱们来看AppRuntime

[app_main.cpp]

class AppRuntime : public AndroidRuntime

其继承于AndroidRuntime,可是并无在其中找到start方法,那么应该在AndroidRuntime中了

[AndroidRuntime.cpp]

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    

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

    /*
     * 注册JNI函数.
     */
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

    /*
     * 传递给java层的ZygoteInit.main函数的参数
     */
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;

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

    for (size_t i = 0; i < options.size(); ++i) {
        jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
        assert(optionsStr != NULL);
        env->SetObjectArrayElement(strArray, i + 1, optionsStr);
    }

    /*
     *反射调用java层的ZygoteInit.main函数
     * 
     */
    char* slashClassName = toSlashClassName(className);
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        
    } else {
        //看到了吧 ,main
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
           
        } else {
            env->CallStaticVoidMethod(startClass, startMeth, strArray);

        }
    }
   
}

咱们分析到了Native层Zygote的启动,至于Java中ZygoteInit.main函数咱们来看一下

[ZygoteInit.java]

public static void main(String argv[]) {
    try {
        ......

        boolean startSystemServer = false;
        String socketName = "zygote";
        String abiList = null;
        for (int i = 1; i < argv.length; i++) {
            if ("start-system-server".equals(argv[i])) {//进入该分支
                
                startSystemServer = true;
            } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                abiList = argv[i].substring(ABI_LIST_ARG.length());
            } else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
                socketName = argv[i].substring(SOCKET_NAME_ARG.length());
            } else {
                throw new RuntimeException("Unknown command line argument: " + argv[i]);
            }
        }

        if (abiList == null) {
            throw new RuntimeException("No ABI list supplied.");
        }

        //创建IPC通讯服务端zygote及系统中其余程序的通讯没有使用Binder,而是采用了基于AF_UNIX类型的Socket

        registerZygoteSocket(socketName);
        ......
        
        if (startSystemServer) {
            //启动SystemServer进程
            startSystemServer(abiList, socketName);
        }

        //处理来自上面的socket的请求
        runSelectLoop(abiList);

        closeServerSocket();
    } catch (MethodAndArgsCaller caller) {
        //这里须要注意
        caller.run();
    } catch (RuntimeException ex) {
        Log.e(TAG, "Zygote died with exception", ex);
        closeServerSocket();
        throw ex;
    }
}

小结

zygote"生下"了SystemServer进程,而后就去等待请求了,看下图

SystemServer

SystemServer进程做为zygote的大儿子,其任务也是很多啊。咱们来看其启动过程。

SystemServer的启动

[ZygoteInit.java]

private static boolean startSystemServer(String abiList, String socketName)
        throws MethodAndArgsCaller, RuntimeException {
    long capabilities = posixCapabilitiesAsBits(
        OsConstants.CAP_BLOCK_SUSPEND,
        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
    );
    /* Hardcoded command line to start the system server */
    String args[] = {
        "--setuid=1000",
        "--setgid=1000",
        "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007",
        "--capabilities=" + capabilities + "," + capabilities,
        "--nice-name=system_server",
        "--runtime-args",
        "com.android.server.SystemServer",
    };
    ZygoteConnection.Arguments parsedArgs = null;

    int pid;

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

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

    /* 若是pid为零,则表示处于子进程中,也就是处于system_server进程中。*/
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            waitForSecondaryZygote(socketName);
        }
        //system_server进程的工做
        handleSystemServerProcess(parsedArgs);
    }

    return true;
}

SystemServer的重要使命

SystemServer进程启动以后,便在其进程中调用handleSystemServerProcess方法完成其重要使命。

[ZygoteInit.java]

private static void handleSystemServerProcess(
        ZygoteConnection.Arguments parsedArgs)
        throws ZygoteInit.MethodAndArgsCaller {

    ......
    //获取SystemServer的类路径
    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    ......
    if (parsedArgs.invokeWith != null) {
       
    } else {//咱们是进入这个分支
        //获取SystemServer的类加载器
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
            Thread.currentThread().setContextClassLoader(cl);
        }

        //调用RuntimeInit的zygoteInit方法
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
    }


}

跟进RuntimeInit.java

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    ......
    //常规的初始化
    commonInit();
    //① native层的初始化
    nativeZygoteInit();
    //② java层的初始化
    applicationInit(targetSdkVersion, argv, classLoader);
}

SystemServer native层的初始化

zygoteInitNative,是一个native函数,实如今
AndroidRuntime.cpp中

[AndroidRuntime.cpp]

static AndroidRuntime* gCurRuntime = NULL;

static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    
    gCurRuntime->onZygoteInit();
}

[app_main.cpp]

virtual void onZygoteInit()
{
    
    //这里看到了咱们的ProcessState,咱们在介绍Binder相关知识的时候常常看到它
    sp<ProcessState> proc = ProcessState::self();
    
    //看这个名字估计是启动线程池把
    proc->startThreadPool();
}

进程惟一的ProcessState

ProcessState self函数采用了单例模式,根据这个以及Process State的名字这很明确地告诉了咱们一个信息:每一个进程只有一个ProcessState对象

[ProcessState.cpp]

sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    //gProcess是在Static.cpp中定义的一个全局变量。
    //程序刚开始执行,gProcess必定为空。
    if (gProcess != NULL) {
        return gProcess;
    }
    //建立一个ProcessState对象,并赋值给gProcess。
    gProcess = new ProcessState;
    return gProcess;
}

再来看ProcessState的构造函数。 这个函数很是重要,它悄悄
地打开了Binder设备,关于Binder更多知识可参看Android开发之漫漫长途 Ⅷ——Android Binder(也许是最容易理解的)

[ProcessState.cpp]

ProcessState::ProcessState()
    : mDriverFD(open_driver())//这里的open_driver()函数
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(NULL)
    , mBinderContextUserData(NULL)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
{
    if (mDriverFD >= 0) {
        /*
        BIDNER_VM_SIZE定义为(1*1024*1024)-(4096*2)=1M-8K
        mmap的用法但愿读者man一下,不过这个函数真正的实现和驱动有关系,而Binder驱
        动会分配一块内存来接收数据。
        */

       
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
    } 
}


static int open_driver()
{
    int fd=open("/dev/binder",O_RDWR);//打开/dev/binder设备。
    if(fd>=0){
        ......
        size_t maxThreads=15;
        //经过ioctl方式告诉binder驱动,这个fd支持的最大线程数是15个。
        result=ioctl(fd,BINDER_SET_MAX_THREADS,&maxThreads);
    }
    return fd;
    ......
}

SystemServer的Binder线程

咱们再来看proc->startThreadPool();

[ProcessState.cpp]

void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    //若是已经startThreadPool的话,这个函数就没有什么实质做用了
    if (!mThreadPoolStarted) {
        mThreadPoolStarted = true;
        //注意,传进去的参数是true。
        spawnPooledThread(true);
    }
}

void ProcessState::spawnPooledThread(bool isMain)
{
    //若是已经startThreadPool的话,这个函数就没有什么实质做用了
    if (mThreadPoolStarted) {
        String8 name = makeBinderThreadName();
        //这里建立PoolThread参数是true
        sp<Thread> t = new PoolThread(isMain);
        //run函数
        t->run(name.string());
    }
}

PoolThread是在ProcessState中定义的一个Thread子类,
它的实现以下所示

class PoolThread : public Thread
{
public:
    PoolThread(bool isMain)
        : mIsMain(isMain)
    {
    }
    
protected:
    virtual bool threadLoop()
    {
        IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
    }
    
    const bool mIsMain;
};

**在Thread类的run方法执行后,调用底层库建立线程,并执行回调方法_ threadLoop,_threadLoop内部有个while循环,循环调用threadLoop()函数处理数据, 并根据threadLoop()的返回值决定循环继续或者退出。当threadLoop()返回true时,若是requestExit没有被调用,则threadLoop会再次调用,当返回false时,线程退出。**

咱们能够在PoolThread中看到threadLoop()方法,也就是说t->run(name.string());的运行会致使循环调用PoolThread的threadLoop()方法。

IPCThreadState

IPCThreadState也是一个单例,不过是线程单例,即每个线程都有一个IPCThreadState

[IPCThreadState.cpp]

IPCThreadState* IPCThreadState::self()
{
    if (gHaveTLS) {
restart:
        const pthread_key_t k = gTLS;
        /*
        TLS是Thread Local Storage(线程本地存储空间)的简称。这里只需知晓:这种空间每一个线程都有,并且线程间不共享这些空间。
        经过pthread_getspecific/pthread_setspecific函数能够获取/设置这些空间
        中的内容。
        从线程本地存储空间中得到保存在其中的IPCThreadState对象。
        有调用pthread_getspecific的地方,确定也有调用pthread_setspecific的地
        方。
        */
        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
        if (st) return st;
        //new一个对象,构造函数中会调用pthread_setspecific
        return new IPCThreadState;
    }
    
    if (gShutdown) return NULL;
    
    pthread_mutex_lock(&gTLSMutex);
    if (!gHaveTLS) {
        if (pthread_key_create(&gTLS, threadDestructor) != 0) {
            pthread_mutex_unlock(&gTLSMutex);
            return NULL;
        }
        gHaveTLS = true;
    }
    pthread_mutex_unlock(&gTLSMutex);
    goto restart;
}

接下来咱们有必要看一下其构造函数了

IPCThreadState::IPCThreadState()
: mProcess(ProcessState::self()),
  mMyThreadId(gettid()),
  mStrictModePolicy(0),
  mLastTransactionBinderFlags(0)
{
    //在构造函数中,把本身设置到线程本地存储中去。
    pthread_setspecific(gTLS, this);
    clearCaller();
    //mIn和mOut是两个Parcel。 把它当作是发送和接收命令的缓冲区便可
    mIn.setDataCapacity(256);
    mOut.setDataCapacity(256);
}

每一个线程都有一个IPCThreadState,每一个IPCThreadState中
都有一个mIn、 一个mOut,其中,mIn是用来接收来自Binder设
备的数据的,而mOut则是用来存储发往Binder设备的数据的。

接下来得来看看joinThreadPool了

void IPCThreadState::joinThreadPool(bool isMain)//此时isMain为true
{
    //向mOut中写入BC_ENTER_LOOPER
    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
   //设置前台调度策略
    set_sched_policy(mMyThreadId, SP_FOREGROUND);
        
    status_t result;
    do {
        processPendingDerefs();
        //处理下一条指令
        result = getAndExecuteCommand();

        if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
            ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
                  mProcess->mDriverFD, result);
            abort();
        }
        
        
        if(result == TIMED_OUT && !isMain) {
            break;//非主线程出现timeout则线程退出
        }
    } while (result != -ECONNREFUSED && result != -EBADF);

    
     //向mOut中写入BC_EXIT_LOOPER
    mOut.writeInt32(BC_EXIT_LOOPER);
    /false表明bwr数据的read_buffer为空
    talkWithDriver(false);
}

咱们在joinThreadPool中又看到了一个do while循环,SystemServer进程建立了主线程以后便加入了Binder线程池,而且永不退出的线程

//这里建立PoolThread参数是true
sp<Thread> t = new PoolThread(isMain);
//run函数
t->run(name.string());

也就是说代码循环执行threadLoop()函数时

virtual bool threadLoop()
{
    //主线程被阻塞在这里了
    IPCThreadState::self()->joinThreadPool(mIsMain);
    
    return false;
}

SystemServer native层的初始化小结

SystemServer Native层的初始化主要是创建了与Binder设备的通讯,完成这项工做的实际是SystemServer的主线程。也是说目前SystemServer进程已有一个线程与Binder通讯。而且Binder驱动程序会根据一些条件来创建新的普通的Binder线程来减低交互压力。

SystemServer java层的初始化

分析的入口是
[RuntimeInit.java]

applicationInit(targetSdkVersion, argv, classLoader);

跟进

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    ......
    final Arguments args;
    try {
        args = new Arguments(argv);
    } catch (IllegalArgumentException ex) {
       
        return;
    }
    ......
    invokeStaticMain(args.startClass, args.startArgs, classLoader);
}

跟进invokeStaticMain

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
        throws ZygoteInit.MethodAndArgsCaller {
    Class<?> cl;
    //反射类,这里是SystemServer类
    try {
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }
    //反射SystemServer类main函数
    Method m;
    try {
        m = cl.getMethod("main", new Class[] { String[].class });
    } catch (NoSuchMethodException ex) {
        throw new RuntimeException(
                "Missing static main on " + className, ex);
    } catch (SecurityException ex) {
        throw new RuntimeException(
                "Problem getting static main on " + className, ex);
    }

    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        throw new RuntimeException(
                "Main method is not public and static on " + className);
    }

   //抛出一个异常
    throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}

既然有抛出异常,确定在哪里捕获了这个异常。咱们一层层回顾,最终在最初调用startSystemServer函数的ZygoteInit的main函数中找到了

catch (MethodAndArgsCaller caller) {
        caller.run();
    }

调用caller.run();反射调用SystemServer类的main方法

兜兜转转咱们终于到了SystemServer。在其main方法中,咱们开启了Android的重要系统服务,如ActivityManagerService等,并把服务注册入了ServiceManager大管家。

[SystemServer.java]

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

private void run() {
    ......

    // 准备main looper
    Looper.prepareMainLooper();

    // 初始化native服务
    System.loadLibrary("android_servers");



    //初始化Context
    createSystemContext();

    //建立系统服务管家.
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

    // 开启服务.
    try {
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
    } catch (Throwable ex) {
        Slog.e("System", "******************************************");
        Slog.e("System", "************ Failure starting system services", ex);
        throw ex;
    }

    // For debug builds, log event loop stalls to dropbox for analysis.
    if (StrictMode.conditionallyEnableDebugLogging()) {
        Slog.i(TAG, "Enabled StrictMode for system server main thread.");
    }

    // 永远 loop
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

SystemServer小结

SystemServer的工做主要包含两部分

  1. Binder相关工做
  2. 开启各类系统服务

经历了上述过程,获得了如图所示的结构

咱们的APP进程

咱们用Android Studio编写一个Hello World程序,编译,安装到手机上。Android Studio 是经过adb 工具作到的。
咱们也可使用下面的安装apk

adb install HelloWorld.apk

而后启动某个Activity

adb shell am start -n 包名/包名.活动名

上面的命令行最终会调用到AMS的startActivityAndWait函数来处理此次启动请求。具体过程咱们这里不分析,咱们这里只须要知道AMS的startActivityAndWait函数经过Socket与zygote进程交互,并最终致使zygote 也经过fork的方式繁殖一个进程,而咱们以后的操做有了载体。

咱们在上面的知识中说到zygote在分裂出SystemServer后,便陷入沉睡等待请求,那么谁会向它发请求,它又是如何处理请求呢。
咱们知道在启动Activity的时候,若是这个Activity附属于一个还没有启动的进程,那么显然咱们要先启动进程。启动进程的请求由AMS的startProcessLocked发起,先来看AMS的startProcessLocked函数
[ActivityManagerService.java]

private final void startProcessLocked(ProcessRecord app, String hostingType,
        String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
        
        .....
        boolean isActivityProcess = (entryPoint == null);
        //这里传入的entryPoint==null因此entryPoint被赋值为android.app.ActivityThread
        if (entryPoint == null) entryPoint = "android.app.ActivityThread";
        .....
        //调用Process.start
        Process.ProcessStartResult startResult = Process.start(entryPoint,
                app.processName, uid, uid, gids, debugFlags, mountExternal,
                app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                app.info.dataDir, entryPointArgs);
        
        .....
}

跟进[Process.java]

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 abi,
                              String instructionSet,
                              String appDataDir,
                              String[] zygoteArgs) {
    try {
        //processClass为android.app.ActivityThread
        return startViaZygote(processClass, niceName, uid, gid, gids,
                debugFlags, mountExternal, targetSdkVersion, seInfo,
                abi, instructionSet, appDataDir, zygoteArgs);
    } catch (ZygoteStartFailedEx ex) {
        Log.e(LOG_TAG,
                "Starting VM process through Zygote failed");
        throw new RuntimeException(
                "Starting VM process through Zygote failed", ex);
    }
}

继续跟进startViaZygote

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 abi,
                              String instructionSet,
                              String appDataDir,
                              String[] extraArgs)
                              throws ZygoteStartFailedEx {
    synchronized(Process.class) {
        ArrayList<String> argsForZygote = new ArrayList<String>();

        //一系列参数设置
        argsForZygote.add("--runtime-args");
        argsForZygote.add("--setuid=" + uid);
        argsForZygote.add("--setgid=" + gid);
        if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {
            argsForZygote.add("--enable-jni-logging");
        }
        if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {
            argsForZygote.add("--enable-safemode");
        }
        if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {
            argsForZygote.add("--enable-debugger");
        }
        if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {
            argsForZygote.add("--enable-checkjni");
        }
        if ((debugFlags & Zygote.DEBUG_ENABLE_JIT) != 0) {
            argsForZygote.add("--enable-jit");
        }
        if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {
            argsForZygote.add("--generate-debug-info");
        }
        if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {
            argsForZygote.add("--enable-assert");
        }
        if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {
            argsForZygote.add("--mount-external-default");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {
            argsForZygote.add("--mount-external-read");
        } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {
            argsForZygote.add("--mount-external-write");
        }
        argsForZygote.add("--target-sdk-version=" + targetSdkVersion);

        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);
        }

        if (instructionSet != null) {
            argsForZygote.add("--instruction-set=" + instructionSet);
        }

        if (appDataDir != null) {
            argsForZygote.add("--app-data-dir=" + appDataDir);
        }

        argsForZygote.add(processClass);

        if (extraArgs != null) {
            for (String arg : extraArgs) {
                argsForZygote.add(arg);
            }
        }
        //调用zygoteSendArgsAndGetResult
        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
    }
}

继续

private static ProcessStartResult zygoteSendArgsAndGetResult(
        ZygoteState zygoteState, ArrayList<String> args)
        throws ZygoteStartFailedEx {
    try {
        //写入数据,发起请求
        final BufferedWriter writer = zygoteState.writer;
        final DataInputStream inputStream = zygoteState.inputStream;

        writer.write(Integer.toString(args.size()));
        writer.newLine();

        int sz = args.size();
        for (int i = 0; i < sz; i++) {
            String arg = args.get(i);
            if (arg.indexOf('\n') >= 0) {
                throw new ZygoteStartFailedEx(
                        "embedded newlines not allowed");
            }
            writer.write(arg);
            writer.newLine();
        }

        writer.flush();

        // 等待结果
        ProcessStartResult result = new ProcessStartResult();
        result.pid = inputStream.readInt();
        if (result.pid < 0) {
            throw new ZygoteStartFailedEx("fork() failed");
        }
        result.usingWrapper = inputStream.readBoolean();
        return result;
    } catch (IOException ex) {
        zygoteState.close();
        throw new ZygoteStartFailedEx(ex);
    }
}

zygote收到请求后调用ZygoteConnection的runOnce方法

[ZygoteConnection.java]

boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
    
    String args[];
    Arguments parsedArgs = null;
    ......
    try{
        //读取SystemServer发送来的参数
        args = readArgumentList();
    }
    ......
    parsedArgs = new Arguments(args);
    ......
    pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
                    parsedArgs.appDataDir);
    ......
    if (pid == 0) {
        //子进程  
        handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);

        return true;
    }
    ......
}

private void handleChildProc(Arguments parsedArgs,
        FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
        throws ZygoteInit.MethodAndArgsCaller {
   

    if (parsedArgs.invokeWith != null) {
       
    } else {
        //这个函数咱们上面已经分析了  

        //常规初始化
        //native层初始化,这是咱们的App生来就能使用Binder的缘由
        //java层初始化,这里咱们像SystemServer同样反射调用android.app.ActivityThread的main函数
        RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion,
                parsedArgs.remainingArgs, null /* classLoader */);
    }
}

咱们的APP进程与SystemServer进程的异同

之因此比较这二者,是由于他们都是zygote的孩子。

相同点

咱们的App与SystemServer相同,生来就支持Binder通讯,这一步是经过native层初始化作到的,其内部打开了Binder设备,并建立了一个主线程与Binder通讯。

不一样点

SystemServerjava初始化反射调用了SystemServer的main方法,并在其中开启了Android的诸多重要系统服务,而咱们的App的,则是反射调用了android.app.ActivityThread的main函数,在该函数中,与AMS所在SystemServer进程创建了联系,并初始化Looper等待消息,关于这部份内容可参看Android开发之漫漫长途 Ⅶ——Android消息机制(Looper Handler MessageQueue Message)

Activity Window View等概念

先有盘古后有天,三清更在盘古前。经过命令am start启动的Acitivty,Activity附属的进程已经启动了,那么Activity是何时建立的呢,
AMS的startActivityAndWait最后会调用到ActivityStackSupervisor类的realStartActivityLocked函数,而该函数内部经过Binder方式调用了android.app.ActivityThread的scheduleLaunchActivity方法

[android.app.ActivityThread.java]

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
            CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
            int procState, Bundle state, PersistableBundle persistentState,
            List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
            boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

        updateProcessState(procState, false);

        ActivityClientRecord r = new ActivityClientRecord();

        r.token = token;
        r.ident = ident;
        r.intent = intent;
        r.referrer = referrer;
        r.voiceInteractor = voiceInteractor;
        r.activityInfo = info;
        r.compatInfo = compatInfo;
        r.state = state;
        r.persistentState = persistentState;

        r.pendingResults = pendingResults;
        r.pendingIntents = pendingNewIntents;

        r.startsNotResumed = notResumed;
        r.isForward = isForward;

        r.profilerInfo = profilerInfo;

        r.overrideConfig = overrideConfig;
        updatePendingConfiguration(curConfig);
        //sendMessage
        sendMessage(H.LAUNCH_ACTIVITY, r);
    }

sendMessage(H.LAUNCH_ACTIVITY, r);最终是由android.app.ActivityThread的内部类H的对象mH.sendMessage(msg);这个内部类H是继承自Handler的。因此一切也就明了了,咱们来看H的handleMessage

public void handleMessage(Message msg) {
        ......
        switch (msg.what) {
            case LAUNCH_ACTIVITY: {
                
                final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                r.packageInfo = getPackageInfoNoCheck(
                        r.activityInfo.applicationInfo, r.compatInfo);
                //调用handleLaunchActivity
                handleLaunchActivity(r, null);
            break;
            ......
        }
    ......
}

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ......
    //调用performLaunchActivityy
    Activity a = performLaunchActivity(r, customIntent);
    ......
   
}

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ......
    
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        //建立activity
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        ......
    } catch (Exception e) {
        ......
    }

    ......
    try {
        //建立Application
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        if (activity != null) {
            ......
            //回调activity的attach方法
            activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor);

    }
    return activity;
}

而在Activity的attach方法中咱们能够看到

final void attach(Context context, ActivityThread aThread,
        Instrumentation instr, IBinder token, int ident,
        Application application, Intent intent, ActivityInfo info,
        CharSequence title, Activity parent, String id,
        NonConfigurationInstances lastNonConfigurationInstances,
        Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
    .....
    //建立PhoneWindow
    mWindow = new PhoneWindow(this);
    mWindow.setCallback(this);
}

想知道关于Window更多的相关知识,可参看Android开发之漫漫长途 Ⅱ——Activity的显示之Window和View(1)以及Android开发之漫漫长途 Ⅱ——Activity的显示之Window和View(2)

小结


本篇总结

本篇是对前面博客的一个小总结,更多细节可参看前面几篇文章,下面给出连接

  1. 你想知道Activity的生命周期以及在Activity生命周期开始以前发生了什么吗?请参看Android开发之漫漫长途 Ⅰ——Android系统的创世之初以及Activity的生命周期
  2. 你想知道更多关于Window和View的知识吗?请参看Android开发之漫漫长途 Ⅱ——Activity的显示之Window和View(1)以及Android开发之漫漫长途 Ⅱ——Activity的显示之Window和View(2)
  3. 你对View的绘制体系有兴趣吗或者你还在迷惑onMeasure、onDraw、onLayout等方法吗?请参看Android开发之漫漫长途 Ⅳ——Activity的显示之ViewRootImpl初探以及Android开发之漫漫长途 Ⅴ——Activity的显示之ViewRootImpl的PreMeasure、WindowLayout、EndMeasure、Layout、Draw以及Android开发之漫漫长途 番外篇——自定义View的各类姿式1
  4. 你对View的事件体系有兴趣吗或者你还在头疼滑动冲突所带来的问题吗?请参看Android开发之漫漫长途 Ⅵ——图解Android事件分发机制(深刻底层源码)以及Android开发之漫漫长途 番外篇——自定义View的各类姿式2
  5. 你对Binder机制有兴趣吗或者你还在呐喊到底什么是Binder吗?请参看Android开发之漫漫长途 VIII——Android Binder(也许是最容易理解的)以及Android开发之漫漫长途 IX——完全掌握Binder
  6. 你对Android性能优化有兴趣吗或者你正在苦恼性能优化无从着手吗?请参看Android开发之漫漫长途 番外篇——内存泄漏分析与解决以及Android开发之漫漫长途 X——Android序列化

下篇预告

下篇咱们来说一下Fragment相关知识,读者若是有哪里不清楚,能够留言给我,有必要的话,单开一篇文章来共同交流。


此致,敬礼

相关文章
相关标签/搜索