[Android]你不知道的Android程式化(2)--建立程式

Cang_Wang發表於2018-01-04

大家好,我係蒼王。

以下是我這個系列的相關文章,有興趣可以參考一下,可以給個喜歡或者關注我的文章。

[Android]如何做一個崩潰率少於千分之三噶應用app--章節列表
[Android]你不知道的Android程式化--程式資訊

Android如何建立一個程式?
下面是簡述:


[Android]你不知道的Android程式化(2)--建立程式
Zygote初始化圖

(1)Android系統啟動的時候會啟動Zygote服務(執行ZygoteInit.java)。
(2)Zygote程式啟動會做三件事。
*建立socket服務端,監聽ActivityManagerService程式的建立請求。
*初始化一些SDK資訊
*最後Zygote fork()建立出SystemService 服務,Zygote.forkSystemServer建立。
(3)SystemService 也會執行三件事
*關閉socket非zygote程式允許監聽
*獲取Dalvim虛擬機器去執行RunTimeInit
*初始化各個系統服務

當應用啟動時
(1)AMS讀取到啟動應用的資訊,通過socket請求Zygote孵化應用的程式,Zygote.forkAndSpecialize建立。
(2)Zygote是會將資訊傳遞到Native層中,然後Linux使用fork()方法來孵化程式。
(3)fork()會給每個程式啟動一個pid(process Id),然後我們通過adb命令就可以看到一些程式資訊了。

四大元件執行的程式

1.activity、service、receiver 和 provider四大元件均支援 android:process 屬性,該屬性可以指定在四大元件哪個程式中執行。
2.application元素支援 android:process 屬性,以設定適用於所有元件的預設值。
3.如果記憶體不足,而其他為使用者提供更緊急服務的程式又需要記憶體時,Android 可能會決定在某一時刻關閉某一程式。在被終止程式中執行的應用元件也會隨之銷燬。 當這些元件需要再次執行時,系統將為它們重啟程式。

Android啟動程式的方法

1.使用AndroidManifest中的的android:process來達到多程式的目的。如果android:process的value值以冒號開頭的話,那麼該程式就是私有程式,如果是以其他字元開頭,那麼就是公有程式,這樣擁有相同 ShareUID 的不同應用可以跑在同一程式裡
2.通過JNI利用C/C++,呼叫fork()方法來生成子程式。

Android關閉程式的方法

關閉當前程式
android.os.Process.killProcess(android.os.Process.myPid());
killProcess的方法其實際是傳送訊號到Native,讓linux通過pid殺死程式。
這裡只介紹關閉自身程式,因為並不涉及到要控制關閉其他程式的情況。
如果有興趣想了解可以檢視
Android程式退出徹底關閉程式的方法
Android結束程式的方法

Android process啟動流程

[Android]你不知道的Android程式化(2)--建立程式
程式建立流程

關於應用內啟動程式,需要深入瞭解AMS的原始碼。
1.三個判斷程式資訊的入口,通過ActivityRecord(Activity)中的processName來獲取到Process資訊。
Activity->ActivityStackSupervisor.java
Service->ActiveService.java
Broadcast->BroadcastQueue
三個檔案都對呼叫AMS的startProcessLock函式。
2.AMS中有四個startProcessLock的函式,之後會呼叫Process.start的函式。
其需要呼叫android.app.ActivityThread為entrypoint入口。
3.Process.start 中會呼叫startViaZygote函式,然後拼接native命令,呼叫
zygoteSendArgsAndGetResult函式,編寫位元組流傳送到ZygoteConnection和接收建立結果
4.Zygote是通過socket的方式接收位元組流的方式互動,接收到後會觸發ZygoteConnection.runOnce()的函式,讀取位元組流資料,然後通過Zygote.forkAndSpecialize告訴native建立程式,handleChildProc會傳送給WrapperInit.execApplication,拼接native命令,轉發到Zygote.execShell來反射entrypoint類即android.app.ActivityThread入口初始化程式。

這裡給大家推薦一篇分析,雖然之後的原始碼有所改動,但是其啟動邏輯並沒有改變。
原始碼分析Android 應用程式的啟動過程

需要注意的是

1.Service不開啟新程式,預設會和Activity跑在同一個主執行緒(UI執行緒)上,所以Service如果有耗時操作請一定要啟動執行緒處理。
2.ContentProvider如果App沒有啟動時,會被預設啟動為一個新的程式,如果App存在,沒有特定指定程式,會和現有的App執行在同一個程式。

本節就到這裡。

你只能向前跑,才能待在原地。

[Android]你不知道的Android程式化(2)--建立程式
Android程式化交流


相關文章