該文章是一個系列文章,是本人在Android開發的漫漫長途上的一點感想和記錄,我會盡可能按照先易後難的順序進行編寫該系列。該系列引用了《Android開發藝術探索》以及《深刻理解Android 卷Ⅰ,Ⅱ,Ⅲ》中的相關知識,另外也借鑑了其餘的優質博客,在此向各位大神表示感謝,膜拜!!!另外,本系列文章知識可能須要有必定Android開發基礎和項目經驗的同窗才能更好理解,也就是說該系列文章面向的是Android中高級開發工程師。html
上面十幾篇文章咱們從Android的創世之初到了Activity顯示以及View的繪製、事件體系,咱們也分析了Binder和Handler。讀者是否是以爲我這個系列要完了呀。那大家就大錯特錯了。介紹前面的知識咱們是爲了後面的知識打底的。那麼本篇文章呢,是對前面文章的一個總結。畢竟一會兒放出那麼多東西,我怕大家的當心臟已經爆棚了。因此本篇文章咱們再梳理一下。java
注:前面文章咱們主要講了和顯示相關的知識如Activity、Window、View等android
注:如下源碼來自android-6.0.0_r5c++
咱們在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進程的重要工做,咱們的重要進程如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自己是一個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的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進程做爲zygote的大兒子,其任務也是很多啊。咱們來看其啓動過程。
[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進程啓動以後,便在其進程中調用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); }
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 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; ...... }
咱們再來看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.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層的初始化主要是創建了與Binder設備的通訊,完成這項工做的實際是SystemServer的主線程。也是說目前SystemServer進程已有一個線程與Binder通訊。而且Binder驅動程序會根據一些條件來創建新的普通的Binder線程來減低交互壓力。
分析的入口是
[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的工做主要包含兩部分
經歷了上述過程,獲得瞭如圖所示的結構
咱們用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 */); } }
之因此比較這二者,是由於他們都是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)。
先有盤古後有天,三清更在盤古前。經過命令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)
本篇是對前面博客的一個小總結,更多細節可參看前面幾篇文章,下面給出連接
下篇咱們來說一下Fragment相關知識,讀者若是有哪裏不清楚,能夠留言給我,有必要的話,單開一篇文章來共同交流。
此致,敬禮