咱們熟知通常 Android 工程師都是在應用層上開發,不會涉及系統源碼,可是若是你想往底層發展,或者深刻插件化、Framework 系統層等開發工做,若是不瞭解 Android 源碼但是不行的,那麼接下來我基於本身的理解跟學習來記錄跟 Android 開發息息相關的源碼分析,大概從 Android 中的 SystemServer 啓動、四大組件啓動、AMS、PMS 等幾個維度來介紹,下面是個人計劃,固然在將來也有可能改變。java
尚未關注的小夥伴,能夠先關注一波,系列文章會持續更新。android
Android 8.0 源碼分析 (一) SystemServer 進程啓動web
Android 8.0 源碼分析 (二) Launcher 啓動數組
Android 8.0 源碼分析 (三) 應用程序進程建立到應用程序啓動的過程app
Android 8.0 源碼分析 (四) Activity 啓動框架
Android 8.0 源碼分析 (五) Service 啓動socket
Android 8.0 源碼分析 (六) BroadcastReceiver 啓動ide
Android 8.0 源碼分析 (七) ContentProvider 啓動函數
前面 2 篇咱們學習了 Android 的系統服務進程啓動和桌面 Launcher 的啓動,那麼基於前面學的內容,這一篇將帶來應用程序進程的啓動過程分析,若是對 Zygote、SystemServer、Launcher 啓動原理還不瞭解的建議先看下我前面文章。oop
想要啓動一個應用程序,首先要保證這個應用程序所須要的應用程序進程已經啓動。 AMS 在啓動應用程序時會檢查這個應用程序須要的應用程序進程是否存在,不存在就會請求 Zygote 進程啓動須要的應用程序進程。在 Android 8.0 源碼分析 (一) SystemServer 進程啓動 中咱們知道在 Zygote 的 Java 框架層中會建立一個 Server 端的 Socket , 這個 Socket 就是用來等待 AMS 請求 Zygote 建立新的應用程序進程。Zygote 進程經過 fock 自身建立的應用程序進程,這樣應用程序就會得到 Zygote 進程在啓動時建立的虛擬機實例。固然,在應用程序進程建立過程當中除了獲取虛擬機實例外,還建立了 Bindler 線程池和消息循環,這樣運行在應用進程中的應用程序就能夠方便的使用 Binder 進行進程間通訊以及處理消息了。
應用程序進程建立過程的步驟比較多,這裏分爲兩個部分來說解,分別是 AMS 發送啓動應用程序進程請求,以及 Zygote 接收請求並建立應用程序進程。
先來看一下 AMS 發送啓動應用程序進程請求過程的時序圖,而後對每個步驟進行詳細分析。
AMS 若是想要啓動應用程序進程,就須要向 Zygote 進程發送建立應用程序進程的請求, AMS 會經過調用 startProcessLocked 函數向 Zygote 進程發送請求,以下所示:
//com.android.server.am; ActivityManagerService.java
/** * 啓動進程的函數 * @param app * @param hostingType * @param hostingNameStr * @param abiOverride * @param entryPoint * @param entryPointArgs */
private final void startProcessLocked( ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs){
...
try {
try {
final int userId = UserHandle.getUserId(app.uid);
AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
/** * 1. 獲取要建立的應用程序進程的 用戶 id */
int uid = app.uid;
int[] gids = null;
int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
if (!app.isolated) {
...
/** * 2. 對 gids 進行建立和賦值 */
if (ArrayUtils.isEmpty(permGids)) {
gids = new int[3];
} else {
gids = new int[permGids.length + 3];
System.arraycopy(permGids, 0, gids, 3, permGids.length);
}
gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
}
...
boolean isActivityProcess = (entryPoint == null);
/** * 3. 若是 entryPoint == null 那麼將 ActivityThread 全類名賦值給 entryPoint */
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
app.processName);
checkTime(startTime, "startProcess: asking zygote to start proc");
ProcessStartResult startResult;
if (hostingType.equals("webview_service")) {
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, entryPointArgs);
} else {
/** * 4. 在 AMS 中調用 start 函數進行通知 Zygote fork 進程 */
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, entryPointArgs);
}
...
}
複製代碼
總結下上面代碼意思,可分爲 4 個步驟:
Process.start 的第一個函數就是 android.app.ActivityThread ,後面小節會用到它,它就是關鍵所在,好了下面咱們看下 Process 的 start 函數:
//android.os; 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 invokeWith, String[] zygoteArgs) {
//1. 經過 ZygoteProcess 調用 start 函數
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}
複製代碼
在 Process.start 靜態函數中咱們看到,又調用了 ZygoteProcess 的 start 函數,其實 ZygoteProcess 是用於與 Zygote 進程保持通訊的狀態,該 start 函數以下:
//android.os; ZygoteProcess.java
public final Process.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 invokeWith, String[] zygoteArgs) {
try {
/** * 繼續調用當前類的 startViaZygote 函數 */
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
}
}
private Process.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 invokeWith, String[] extraArgs) throws ZygoteStartFailedEx {
//建立一個集合 將應用程序進程啓動參數保存
ArrayList<String> argsForZygote = new ArrayList<String>();
// --runtime-args, --setuid=, --setgid=,
// and --setgroups= must go first
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
...//省略部分代碼
synchronized(mLock) {
//繼續調用內部函數
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
複製代碼
經過上面代碼咱們知道主要就是將應用程序進程啓動參數告訴 zygoteSendArgsAndGetResult 而後經過 Socket 傳遞給 zygote 進程,咱們先來看 openZygoteSocketIfNeeded(abi) 實現
//android.os; ZygoteProcess.java
@GuardedBy("mLock")
private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held");
if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
try {
/** * 1. 鏈接 zygote 名稱爲 "zygote" 服務端的 Socket ,創建進程間通訊 */
primaryZygoteState = ZygoteState.connect(mSocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
}
/** * 2. 鏈接 Zygote 主模式返回的 ZygoteState 是否與啓動應用程序進程所須要的 ABI 匹配 */
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
// 若是不匹配,則嘗試鏈接 zygote 輔模式
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) {
try {
/** * 3. 若是不匹配那麼就嘗試鏈接 name 爲 "zygote_secondary" 的 Socket */
secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
} catch (IOException ioe) {
throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
}
}
/** * 4. 鏈接 Zygote 輔模式返回的 ZygoteState 是否與啓動應用程序進程所須要的 ABI 匹配 */
if (secondaryZygoteState.matches(abi)) {
return secondaryZygoteState;
}
//若是都不匹配那麼就拋一個異常
throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}
複製代碼
經過上面的代碼跟註釋咱們知道就是與 zygote 進程經過 Socket 進行一個鏈接,鏈接成功以後會返回一個 ZygoteState,而後對傳遞進來的 abi 進行匹配,這裏鏈接和匹配 abi 涉及到 Zygote 的啓動腳本,感興趣的能夠查閱相關資料,通俗的來說就是若是 Zygote 進程採用的是 init.zygote32_64.rc 腳本啓動,那麼它就是屬於主模式爲 「name」 名稱的服務端 Socket, 若是採用的是 init.zygote64_32.rc 腳本啓動,那麼它就是屬於輔模式爲 「zygote_secondary」 名稱的服務端 Socket。最後若是都不匹配說明鏈接或者匹配異常了。若是鏈接成功以後咱們看 zygoteSendArgsAndGetResult 函數主要作了些什麼工做:
//android.os; ZygoteProcess.java
private static Process.ProcessStartResult zygoteSendArgsAndGetResult( ZygoteState zygoteState, ArrayList<String> args) throws ZygoteStartFailedEx {
...
final BufferedWriter writer = zygoteState.writer;
final DataInputStream inputStream = zygoteState.inputStream;
writer.write(Integer.toString(args.size()));
writer.newLine();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
writer.write(arg);
writer.newLine();
}
writer.flush();
...
}
return result;
} catch (IOException ex) {
zygoteState.close();
throw new ZygoteStartFailedEx(ex);
}
}
複製代碼
經過上面代碼咱們知道,若是與 zygote 進程的服務端 Socket 鏈接成功,那麼就將存儲起來的應用程序進程啓動參數寫入到 ZygoteState 中。最後就是 Zygote 進程接收後的處理工做了,下面一小節來詳細爲你們介紹接收以後的工做。
若是有看過 Android 8.0 源碼分析 (一) SystemServer 進程啓動 該文章的必定清楚,其實 SystemServer 跟應用進程啓動在 Zygote 處理 的方式類似,這裏我們爲了複習一下以前的內容,咱們就再來溫習一遍吧,先來看一個時序圖。
上面咱們講了在溫習一下 ZygoteInit main 函數,那麼咱們在看一下 服務端的 Socket 建立
//com.android.internal.os.ZygoteInit.java
public static void main(String argv[]) {
....
try {
...
//是否開啓 SystemServer 標記
boolean startSystemServer = false;
//服務端 Socket 名稱
String socketName = "zygote";
//根據 JNI 層傳遞過來的信息,來判斷是否啓動系統服務
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)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
/** * 1. 建立服務端的 Socket ,名稱爲 "zygote" */
zygoteServer.registerServerSocket(socketName);
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
/** * 2. 用來預加載資源 */
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
...
if (startSystemServer) {
/** * 3. 啓動 SystemServer 進程 * */
startSystemServer(abiList, socketName, zygoteServer);
}
Log.i(TAG, "Accepting command socket connections");
/** * 4. 等待 AMS 請求 */
zygoteServer.runSelectLoop(abiList);
//清理或者關閉對應的 Socket
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
複製代碼
在上面註釋 1 處經過 registerZygoteSocket 函數來建立一個名稱爲 「name」 的服務端 Socket, 這個 Socket 是用於等待 AMS 發起建立新的應用程序進程的請求,關於 AMS 後面我會詳細講解。註釋 3 啓動服務進程,註釋 4 等待 AMS 的請求,咱們直接看 註釋 4 的代碼實現
// com.android.internal.os ZygoteInit.main->runSelectLoop
void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
/** * 1. 添加得到該 Socket 的 fd 字段的值 */
fds.add(mServerSocket.getFileDescriptor());
peers.add(null);
/** * 死循環等待 AMS 的請求 */
while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()];
/** * 2. 將 fds 信息轉存到 pollFds 數組中。 */
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
throw new RuntimeException("poll failed", ex);
}
/** * 3.對 pollFds 信息進行遍歷 */
for (int i = pollFds.length - 1; i >= 0; --i) {
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
//若是 i == 0 那麼就認爲 服務端 Socket 與客戶端鏈接上了,就是與 AMS 創建了鏈接
if (i == 0) {
/** * 4. */
ZygoteConnection newPeer = acceptCommandPeer(abiList);
//將 ZygoteConnection 添加到 Socket 鏈接列表中
peers.add(newPeer);
//將 ZygoteConnection 的文件描述符 添加到 fds 列表中
fds.add(newPeer.getFileDesciptor());
} else {//若是不等於 0 ,那麼就說明 AMS 向 Zygote 發送了一個建立應用進程的請求
/** * 5. 調用 ZygoteConnection 的 runOnce 函數來建立一個新的應用進程,並在成功建立後將這個鏈接從 Socket 鏈接列表中 peers、fd 列表中關閉 */
boolean done = peers.get(i).runOnce(this);
if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}
複製代碼
經過上面註釋咱們知道,若是 AMS 發來了一個新的請求任務,會走註釋 5 經過 peers.get(i).runOnce(this); 來處理請求數據,咱們直接看 runOnce 函數具體實現:
//com.android.internal.os; ZygoteConnection.java
boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
/** * 1. 獲取應用程序進程的啓動參數 */
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
Log.w(TAG, "IOException on command socket " + ex.getMessage());
closeSocket();
return true;
}
...
int pid = -1;
FileDescriptor childPipeFd = null;
FileDescriptor serverPipeFd = null;
try {
/** * 2. 將獲取到啓動應用程序進程的啓動參數 args 數組 封裝到 Arguments 類型的 parsedArgs 對象中 */
parsedArgs = new Arguments(args);
...
fd = null;
/** * 3. 經過 Zygote 來建立應用程序進程 */
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
parsedArgs.appDataDir);
} catch (ErrnoException ex) {
...
}
try {
//當前代碼邏輯運行在被建立出來的子進程中
if (pid == 0) {
// in child
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
//4. 處理應用程序進程
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
// should never get here, the child is expected to either
// throw Zygote.MethodAndArgsCaller or exec().
return true;
} else {
// in parent...pid of < 0 means failure
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
複製代碼
經過上面代碼咱們知道這裏 runOnce 首先獲取到啓動應用程序進程的參數,而後進行一個 Argument 的包裝,最後經過 Zygote.forkAndSpecialize 建立 AMS 傳遞過來啓動進程信息,內部實際上是 native 函數來進行建立。接下來咱們看 註釋 4 處理建立完成的應用程序進程,以下代碼:
//com.android.internal.os; ZygoteConnection.java
private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr) throws Zygote.MethodAndArgsCaller {
...
if (parsedArgs.invokeWith != null) {
...
} else {
//調用 ZygoteInit 的 zygoteInit 函數
ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}
複製代碼
handleChildProc 內部又調用了 ZygoteInit 的 zygoteInit 函數,具體咱們看下源碼:
// com.android.internal.os ZygoteInit
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
/** * 1. 啓動 Binder 線程池 */
ZygoteInit.nativeZygoteInit();
/** * 2. 進入 ActivityThread 的 main 方法 */
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
複製代碼
註釋 1 處先啓動 Binder 線程池,用於進程間通訊,咱們註解看註釋 2 內部實現
//com.android.internal.os RuntimeInit.java
protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
...
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
Class<?> cl;
try {
/** *1. 經過 className("android.app.ActivityThread" )反射獲得 ActivityThread 類 * className 經過 AMS 等其它地方傳遞過來的,並非惟一 */
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
/** * 2. 拿到 ActivityThread main 函數 */
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
...
} catch (SecurityException ex) {
...
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
...
}
/** * 3. 將 m 、argv 傳入 MethodAndArgsCaller,而後拋一個異常,並在 ZygoteInit.main 中進行捕獲異常 */
throw new Zygote.MethodAndArgsCaller(m, argv);
}
複製代碼
經過上面代碼首先根據 AMS 傳遞過來的啓動參數 android.app.ActivityThread 而後進行反射拿到 ActivityThread 實例,在經過它的實例拿到 main 函數,最後交於 Zygote.MethodAndArgsCaller(m, argv); 異常來處理,直接看 ZygoteInit.main() 函數
//com.android.internal.os.ZygoteInit.java
public static void main(String argv[]) {
....
try {
...
//服務端 Socket 名稱
String socketName = "zygote";
...
/** * 1. 建立服務端的 Socket ,名稱爲 "zygote" */
zygoteServer.registerServerSocket(socketName);
...
/** * 2. 等待 AMS 請求 */
zygoteServer.runSelectLoop(abiList);
} catch (Zygote.MethodAndArgsCaller caller) {
//3. 捕獲到 RuntimeInit applicationInit 中的異常
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
複製代碼
根據註釋 3 咱們知道捕獲到了 RuntimeInit applicationInit 中的異常,而後進入它的 run 函數
////com.android.internal.os Zygote.java
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 {
/** * 1. 這裏就開始執行 ActivityThread main 方法了 */
mMethod.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);
}
}
}
複製代碼
到了這裏 應用程序的進程建立和 應用程序進程的入口 ActivityThread main 都已經執行了,下面咱們來看 ActivityThead main 函數實現:
//android.app; ActivityThread.java
//經過 ZygoteInit 反射調用執行的
public static void main(String[] args) {
...
//1. 主線程消息循環 Looper 建立
Looper.prepareMainLooper();
//2. 建立 ActivityThread 對象
ActivityThread thread = new ActivityThread();
//3. Application,Activity ......入口
thread.attach(false);
//4. 拿到 H -> Handler
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
...
//5. 開啓 Looper 循環,處理主線程消息
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
複製代碼
經過上面代碼咱們知道 ActivityThread main 函數主要作了 5 件事:
咱們直接跳到註釋 3 處
//
private void attach(boolean system) {
....
//1. 拿到 IActivityManager aidl 接口
final IActivityManager mgr = ActivityManager.getService();
try {
//2. 關聯 Application
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
try {
mInstrumentation = new Instrumentation();
//3. 建立系統級別的 Context
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
//4. 建立 Application 對象
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
//5. Application oncreate 生命週期調用
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
...
}
複製代碼
咱們直接看應用程序 Application 建立吧,跳到註釋 4
//android.app; LoadedApk.java
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
...
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
//1. 建立一個新的 Application
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
} catch (Exception e) {
..}
mApplication = app;
if (instrumentation != null) {
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
return app;
}
複製代碼
咱們繼續看註釋 1 的實現
//android.app; Instrumentation.java
public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
//調用內部的 newApplication 函數
return newApplication(cl.loadClass(className), context);
}
static public Application newApplication(Class<?> clazz, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
//反射進行實例化 Application
Application app = (Application)clazz.newInstance();
//執行 Application 生命週期函數 attach
app.attach(context);
return app;
}
複製代碼
到這裏應用程序進程的建立 再到應用程序的 Application 的啓動已經介紹完了
本篇文章涉及到的知識點不少有 Zygote、AMS、ActivityThread、Application 等等,相信若是跟着個人系列文章來閱讀的話,收穫確定仍是有的。
在這裏就簡單的總結下應用程序進程的啓動,首先經過 Launcher 中的點擊事件觸摸手機屏幕中的應用圖標,AMS 會收到啓動應用程序進程的信息,而後經過 Socket 傳遞給 Zygote 進程,Zygote 進程收到 AMS 傳遞過來的啓動信息進行 native 層建立子進程,最後經過反射調用 ActivityThead main 函數,最終在 ActivityThead attach 函數中經過反射實例化了 Application 並執行了對應的生命週期函數 。到這裏該應用程序進程就 執行到了 Application 中了。下一篇文章將爲你們帶來四大組件中的 Activity 源碼分析,敬請期待!