建設物流網(wǎng)站的規(guī)劃網(wǎng)絡營銷戰(zhàn)略的內(nèi)容
概述
在Android系統(tǒng)中,所有的應用程序進程以及系統(tǒng)服務進程SystemServer都是由Zygote進程孕育(fork)出來的,這也許就是為什么要把它稱為Zygote(受精卵)的原因吧。由于Zygote進程在Android系統(tǒng)中有著如此重要的地位,本文將詳細分析它的啟動過程
總體時序
先概述一下總體運行流程,當按電源鍵,首先是加載系統(tǒng)引導程序BootLoader,然后啟動linux內(nèi)核,再啟動init進程,最后Zygote進程啟動完成。理論上Android系統(tǒng)中的所有應用程序理論上都是由Zygote啟動的。Zygote前期啟動啟動服務,后期主要fork程序。
init啟動流程
- 用戶空間的第一個進程,進程號為1(在《深入理解安卓內(nèi)核思想》的257頁里面寫的是0,在這記錄一下)
- 職責
- 創(chuàng)建Zygote
- 初始化屬性服務
- init文件位于源碼目錄system/core/init中
init進程的啟動三個階段
- 啟動電源以及系統(tǒng)的啟動,加載引導程序BootLoader。
- 啟動Linux內(nèi)核
- 啟動init進程。
- 啟動Zygote進程
- 初始化啟動屬性服務。
Zygote進程
- 所有App的父進程,ZygoteInit.main
- Zygote進程,是由init進程通過解析init.rc文件后fork生成的,Zygote進程主要包括
- 加載Zygoteinit類,注冊Zygote Socket服務端套接字
- 加載虛擬機
- 提前加載類PreloadClasses
- 提前加載資源PreLoadResouces
- system_server進程,是由Zygote fork而來,System Server是Zygote孵化出的第一個進程,System Server 負責啟動和管理整個Java FrameWork,包含ActivityManagerService, WorkManagerService,PagerManagerService,PowerManagerService等服務
system_server進程
系統(tǒng)各大服務的載體, SystemServer.main system_server進程從源碼角度來看可以分為,引導服務,核心服務和其他服務
- 引導服務(7個):ActivityManagerService、PowerManagerService、LightsService、DisplayManagerService、PackageManagerService、UserManagerService、SensorService;
- 核心服務(3個):BatteryService、UsageStatsService、WebViewUpdateService;
- 其他服務(70個+):AlarmManagerService、VibratorService等。
ServiceManger進程
bInder服務的大管家
ServiceManager 是Binder IPC通信過程中的守護進程,本身也是一個Binder,但是并沒有采用多線程模型來跟Binder通信,而是自行編寫了binder.c直接和Binder驅動來通信,并且只有一個binder_loop來讀取和處理事務,這樣做的好處是簡單和高效 ServiceManager本身工作相對簡單,其工能查詢和注冊服務
流程圖
ServiceManager 集中管理系統(tǒng)內(nèi)的所有服務,通能過權限控制進程是否有權注冊服務,通過字符串來查找是否有對應的Service,由于ServiceManager進程注冊了Service的死亡通知,那么服務所在的進程死亡后,只需告訴ServiceManager,每個Client通過查詢ServiceManager可以獲取Service的情況
啟動主要包括以下幾個階段
- 打開Binder驅動,并調用mmap()方法分配128k的內(nèi)存映射空間,binder_open
- 注冊成為Binder服務的大管家binder_become_context_manager
- 驗證selinux權限,判斷進程是否有權注冊查看指定服務
- 進入無限循環(huán),處理Client發(fā)來的請求 binder_loop
- 根據(jù)服務的名稱注冊服務,重復注冊會移除之前的注冊信息
- 死亡通知,當所在進程死亡后,調用binder_release方法,然后調用binder_node_release,這個過程發(fā)出死亡通知回調
App進程
- 通過Process.start啟動的App進程ActivityThread.main
- Zygote 孵化出的第一個App進程是Launcher,這是用戶看到的桌面App
- Zygote 還會創(chuàng)建出Browser,Phone,Email等App進程,每個App至少運行在一個進程上
- 所有的App進程都是由Zygote fork而成
3)Zygote進程的啟動
Zygote進程, 一個在Android系統(tǒng)中扮演重要角色的進程. 我們知道Android系統(tǒng)中的兩個重要服務PackageManagerService和ActivityManagerService, 都是由SystemServer進程啟動的, 而這個SystemServer進程本身是Zygote進程在啟動的過程中fork出來的. 這樣一來, 想必我們就知道Zygote進程在Android系統(tǒng)中的重要地位了.
從圖中可得知Android系統(tǒng)中各個進程的先后順序為:
init進程 –-> Zygote進程 –> SystemServer進程 –>應用進程
鏈接
- 在init啟動Zygote時主要是調用app_main.cpp的main函數(shù)中的AppRuntime.start()方法來啟動Zygote進程的;
- 接著到AndroidRuntime的start函數(shù):使用JNI調用ZygoteInit的main函數(shù),之所以這里要使用JNI,是因為ZygoteInit是java代碼。最終,Zygote就從Native層進入了Java FrameWork層。在此之前,并沒有任何代碼進入Java FrameWork層面,因此可以認為,Zygote開創(chuàng)了java FrameWork層。
- /frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
@UnsupportedAppUsagepublic static void main(String argv[]) {ZygoteServer zygoteServer = null;// Mark zygote start. This ensures that thread creation will throw// an error.ZygoteHooks.startZygoteNoThreadCreation();// Zygote goes into its own process group.try {Os.setpgid(0, 0);} catch (ErrnoException ex) {throw new RuntimeException("Failed to setpgid(0,0)", ex);}Runnable caller;try {// Report Zygote start time to tron unless it is a runtime restartif (!"1".equals(SystemProperties.get("sys.boot_completed"))) {MetricsLogger.histogram(null, "boot_zygote_init",(int) SystemClock.elapsedRealtime());}String bootTimeTag = Process.is64Bit() ? "Zygote64Timing" : "Zygote32Timing";TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,Trace.TRACE_TAG_DALVIK);bootTimingsTraceLog.traceBegin("ZygoteInit");RuntimeInit.enableDdms();boolean startSystemServer = false;String zygoteSocketName = "zygote";String abiList = null;boolean enableLazyPreload = false;for (int i = 1; i < argv.length; i++) {if ("start-system-server".equals(argv[i])) {startSystemServer = true;} else if ("--enable-lazy-preload".equals(argv[i])) {enableLazyPreload = 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)) {zygoteSocketName = argv[i].substring(SOCKET_NAME_ARG.length());} else {throw new RuntimeException("Unknown command line argument: " + argv[i]);}}final boolean isPrimaryZygote = zygoteSocketName.equals(Zygote.PRIMARY_SOCKET_NAME);if (abiList == null) {throw new RuntimeException("No ABI list supplied.");}// In some configurations, we avoid preloading resources and classes eagerly.// In such cases, we will preload things prior to our first fork.if (!enableLazyPreload) {bootTimingsTraceLog.traceBegin("ZygotePreload");EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,SystemClock.uptimeMillis());preload(bootTimingsTraceLog);EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,SystemClock.uptimeMillis());bootTimingsTraceLog.traceEnd(); // ZygotePreload} else {Zygote.resetNicePriority();}// Do an initial gc to clean up after startupbootTimingsTraceLog.traceBegin("PostZygoteInitGC");gcAndFinalize();bootTimingsTraceLog.traceEnd(); // PostZygoteInitGCbootTimingsTraceLog.traceEnd(); // ZygoteInit// Disable tracing so that forked processes do not inherit stale tracing tags from// Zygote.Trace.setTracingEnabled(false, 0);Zygote.initNativeState(isPrimaryZygote);ZygoteHooks.stopZygoteNoThreadCreation();zygoteServer = new ZygoteServer(isPrimaryZygote);if (startSystemServer) {
// 使用了forkSystemServer()方法去創(chuàng)建SystemServer進程Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);
// {@code r == null} in the parent (zygote) process, and {@code r != null} in the
// child (system_server) process.if (r != null) {r.run();return;
}
}
Log.i(TAG, "Accepting command socket connections");
// The select loop returns early in the child process after a fork and
// 這里調用了ZygoteServer的runSelectLoop方法來等等ActivityManagerService來請求創(chuàng)建新的應用程序進程
// loops forever in the zygote.caller = zygoteServer.runSelectLoop(abiList);}
catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
throw ex;}
finally
{
if (zygoteServer != null) {zygoteServer.closeServerSocket();
}
}
// We're in the child process and have exited the select loop. Proceed to execute the
// command.if (caller != null) {caller.run();
}
}
其中, 在ZygoteInit的forkSystemServer()方法中啟動了SystemServer進程,forkSystemServer()方法核心代碼 :
private static Runnable forkSystemServer(String abiList, String socketName,ZygoteServer zygoteServer)
{
// 一系統(tǒng)創(chuàng)建SystemServer進程所需參數(shù)的準備工作try {...
/* Request to fork the system server process
*/// 3.1pid = Zygote.forkSystemServer(parsedArgs.uid, parsedArgs.gid,parsedArgs.gids,parsedArgs.runtimeFlags,null,parsedArgs.permittedCapabilities,parsedArgs.effectiveCapabilities);
}
catch (IllegalArgumentException ex)
{throw new RuntimeException(ex);}
/* For child process
*/if (pid == 0) {
if (hasSecondZygote(abiList)) {waitForSecondaryZygote(socketName);}
zygoteServer.closeServerSocket();
// 3.2return handleSystemServerProcess(parsedArgs);
}return null;
}
可以看到,forkSystemServer()方法中,注釋3.1調用了Zygote的forkSystemServer()方法去創(chuàng)建SystemServer進程,其內(nèi)部會執(zhí)行nativeForkSystemServer這個Native方法,它最終會使用fork函數(shù)在當前進程創(chuàng)建一個SystemServer進程。如果pid等于0,即當前是處于新創(chuàng)建的子進程ServerServer進程中,則在注釋3.2處使用handleSystemServerProcess()方法處理SystemServer進程的一些處理工作。
從以上的分析可以得知,Zygote進程啟動中承擔的主要職責如下:
- 1、創(chuàng)建AppRuntime,執(zhí)行其start方法,啟動Zygote進程。。
- 2、創(chuàng)建JVM并為JVM注冊JNI方法。
- 3、使用JNI調用ZygoteInit的main函數(shù)進入Zygote的Java FrameWork層。
- 4、使用registerZygoteSocket方法創(chuàng)建服務器端Socket,并通過runSelectLoop方法等等AMS的請求去創(chuàng)建新的應用進程。
- 5、啟動SystemServer進程。
- 調用了handleSystemServerprocess()方法來啟動SystemServer進程。handleSystemServerProcess()方法如下所示:
/*** Finish remaining work for the newly forked system server process.
*/
private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {...
if (parsedArgs.invokeWith != null) {...}
else {ClassLoader cl = null;
if (systemServerClasspath != null) {
// 1cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);}
/** Pass the remaining arguments to SystemServer.
*/// 2return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
在注釋1處,使用了systemServerClassPath和targetSdkVersion創(chuàng)建了一個PathClassLoader。接著,在注釋2處,執(zhí)行了ZygoteInit的zygoteInit()方法,該方法如下所示:
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
{
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
// 1ZygoteInit.nativeZygoteInit();
// 2return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
- zygoteInit()方法的注釋2處,這里調用了RuntimeInit 的 applicationInit() 方法,代碼如下所示:
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) {...
// Remaining arguments are passed to the start class's static mainreturn findStaticMain(args.startClass, args.startArgs, classLoader);
}
在applicationInit()方法中最后調用了findStaticMain()方法:
protected static Runnable findStaticMain(String className, String[] argv,ClassLoader classLoader) {
Class<?> cl;
try {
// 1cl = Class.forName(className, true, classLoader);
}
catch (ClassNotFoundException ex) {
throw new RuntimeException("Missing class when invoking static main " + className,ex);
}
Method m;try {
// 2m = 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);}
/** This throw gets caught in ZygoteInit.main(), which responds
* by invoking the exception's run() method. This arrangement
* clears up all the stack frames that were required in setting
* up the process.
*/// 3return new MethodAndArgsCaller(m, argv);
}
首先,在注釋1處,通過發(fā)射得到了SystemServer類。接著,在注釋2處,找到了SystemServer中的main()方法。最后,在注釋3處,會將main()方法傳入MethodAndArgsCaller()方法中,這里的MethodAndArgsCaller()方法是一個Runnable實例,它最終會一直返回出去,直到在ZygoteInit的main()方法中被使用,如下所示:
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// {@code r == null}
in the parent (zygote) process, and {
@code r != null}
in the
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
可以看到,最終直接調用了這個Runnable實例的run()方法,代碼如下所示:
/*** Helper class which holds a method and arguments and can call them. This is used as part of
* a trampoline to get rid of the initial process setup stack frames.
*/
static class MethodAndArgsCaller 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 {
// 1mMethod.invoke(null, new Object[] {
mArgs });}
catch (IllegalAccessException ex) {throw new RuntimeException(ex);}
catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
}
else if (cause instanceof Error) {
throw (Error) cause;}
throw new RuntimeException(ex);
}
}
}
在注釋1處,這個mMethod就是指的SystemServer的main()方法,這里動態(tài)調用了SystemServer的main()方法,最終,SystemServer進程就進入了SystemServer的main()方法中了。這里還有個遺留問題,為什么不直接在findStaticMain()方法中直接動態(tài)調用SystemServer的main()方法呢?原因就是這種遞歸返回后再執(zhí)行入口方法的方式會讓SystemServer的main()方法看起來像是SystemServer的入口方法,而且,這樣也會清除之前所有SystemServer相關設置過程中需要的堆棧幀。
--------走到 SystemService 進程
- /frameworks/base/services/java/com/android/server/SystemServer.java
接下來我們看看SystemServer的main()方法:
/**
* The main entry point from zygote.
*/
public static void main(String[] args)
{
new SystemServer().run();
}
main()方法中調用了SystemServer的run()方法,如下所示:
private void run() {try {...
// 1Looper.prepareMainLooper();...
// Initialize native services.
// 2System.loadLibrary("android_servers");
// Check whether we failed to shut down last time we tried.
// This call may not return.performPendingShutdown();
// Initialize the system context.createSystemContext();
// Create the system service manager.
// 3mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelizedSystemServerInitThreadPool.get();}
finally {traceEnd();
// InitBeforeStartServices}
// Start services.try {
traceBeginAndSlog("StartServices");
// 4startBootstrapServices();
// 5startCoreServices();
//6startOtherServices();
SystemServerInitThreadPool.shutdown();}
catch (Throwable ex) {Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;}
finally {
traceEnd();
}...
// Loop forever.
// 7Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
在注釋1處,創(chuàng)建了消息Looper。
在注釋2處,加載了動態(tài)庫libandroid_servers.so。
在注釋3處,創(chuàng)建了SystemServerManager,它的作用是對系統(tǒng)服務進行創(chuàng)建、啟動和生命周期管理。
在注釋4處的startBootstarpServices()方法中使用SystemServiceManager啟動了ActivityManagerService、PackageManagerService、PowerManagerService等引導服務。
在注釋5處的startCoreServices()方法中則啟動了BatteryService、WebViewUpdateService、DropBoxManagerService、UsageStatsService4個核心服務。
在注釋6處的startOtherServices()方法中啟動了WindowManagerService、InputManagerService、CameraService等其它服務。這些服務的父類都是SystemService。
可以看到,上面把系統(tǒng)服務分成了三種類型:引導服務、核心服務、其它服務。這些系統(tǒng)服務共有100多個,其中對于我們來說比較關鍵的有:
- 引導服務:ActivityManagerService,負責四大組件的啟動、切換、調度。
- 引導服務:PackageManagerService,負責對APK進行安裝、解析、刪除、卸載等操作。
- 引導服務:PowerManagerService,負責計算系統(tǒng)中與Power相關的計算,然后決定系統(tǒng)該如何反應。
- 核心服務:BatteryService,管理電池相關的服務。
- 其它服務:WindowManagerService,窗口管理服務。
- 其它服務:InputManagerService,管理輸入事件。
很多系統(tǒng)服務的啟動邏輯都是類似的,這里我以啟動ActivityManagerService服務來進行舉例,代碼如下所示:
mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();
SystemServiceManager 的 startService() 方法啟動了ActivityManagerService,該啟動方法如下所示:
@SuppressWarnings("unchecked")
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {final String name = serviceClass.getName();
...try {Constructor<T> constructor = serviceClass.getConstructor(Context.class);
// 1service = constructor.newInstance(mContext);
}
catch (InstantiationException ex) {...
// 2startService(service);return service;
}
finally {Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
在注釋1處使用反射創(chuàng)建了ActivityManagerService實例,并在注釋2處調用了另一個startService()重載方法,如下所示:
public void startService(@NonNull final SystemService service) {
// Register it.
// 1mServices.add(service);
// Start it.long time = SystemClock.elapsedRealtime();
try {
// 2service.onStart();
}
catch (RuntimeException ex)
{
throw new RuntimeException("Failed to start service " + service.getClass().getName()+ ": onStart threw an exception", ex);
}
warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}
在注釋1處,首先會將ActivityManagerService添加在mServices中,它是一個存儲SystemService類型的ArrayList,這樣就完成了ActivityManagerService的注冊。
在注釋2處,調用了ActivityManagerService的onStart()方法完成了啟動ActivityManagerService服務。
除了使用SystemServiceManager的startService()方法來啟動系統(tǒng)服務外,也可以直接調用服務的main()方法來啟動系統(tǒng)服務,如PackageManagerService:
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
這里直接調用了PackageManagerService的main()方法:
public static PackageManagerService main(Context context, Installer installer,boolean factoryTest, boolean onlyCore) {
// Self-check for initial settings.PackageManagerServiceCompilerMapping.checkProperties();
// 1PackageManagerService m = new PackageManagerService(context, installer,factoryTest, onlyCore);
m.enableSystemUserPackages();
// 2ServiceManager.addService("package", m);
// 3final PackageManagerNative pmn = m.new PackageManagerNative();
ServiceManager.addService("package_native", pmn);
return m;
}
在注釋1處,直接新建了一個PackageManagerService實例,
注釋2處將PackageManagerService注冊到服務大管家ServiceManager中,ServiceManager用于管理系統(tǒng)中的各種Service,用于系統(tǒng)C/S架構中的Binder進程間通信,即如果Client端需要使用某個Servcie,首先應該到ServiceManager查詢Service的相關信息,然后使用這些信息和該Service所在的Server進程建立通信通道,這樣Client端就可以服務端進程的Service進行通信了。
7. SystemService 進程總結
SystemService的啟動流程分析至此已經(jīng)完結,經(jīng)過以上的分析可知,SystemService進程被創(chuàng)建后,主要的處理如下:
- 1、啟動Binder線程池,這樣就可以與其他進程進行Binder跨進程通信。
- 2、創(chuàng)建SystemServiceManager,它用來對系統(tǒng)服務進行創(chuàng)建、啟動和生命周期管理。
- 3、啟動各種系統(tǒng)服務:引導服務、核心服務、其他服務,共100多種。應用開發(fā)主要關注引導服務ActivityManagerService、PackageManagerService和其他服務WindowManagerService、InputManagerService即可。