1、init進程啓動
init 進程是Android系統的第一個進程,很多重要職責,例如創建Zygote和屬性服務等。 init位於路勁system、core/init.
1.1引入init進程
1.啓動電源以及系統啓動
2.引導程序Bootloader
3.linux內核啓動
4.init進程啓動
1.2引入init進程
在main函數中system/core/init/init.cpp
int main(int argc, char** argv) {
…
//對屬性服務進行初始化
property_init(); //1
…
//用於設置子進程信號處理函數,如果子進程(zogete進程)異常退出,init進程會調用該函數中設定的信號處理函數來處理
signal_handler_init();//2
…
//啓動屬性服務
start_property-service();//3
…
//解析init.rc配置文件
parser.ParseConfig(“init.rc”);//4
…
//重啓死去的進程
restart_processes();//5
}
註釋2是爲了防止殭屍進程
父進程不知道子進程終止,但是此時系統進程表中還爲它保留了一定的信息,子進程爲殭屍進程。 進程表資源有限。
1.3init.rc
init.rc是一個配置文件,內部由Android初始化語言編寫(Android Init Language)編寫的腳本,它主要包含五種類型語句:
Action、Commands、Services、Options和Import。init.rc的配置代碼如下所示。
system/core/rootdir/init.rc
on init
sysclktz 0
# Mix device-specific information into the entropy pool
copy /proc/cmdline /dev/urandom
copy /default.prop /dev/urandom
...
on boot
# basic network init
ifup lo
hostname localhost
domainname localdomain
# set RLIMIT_NICE to allow priorities from 19 to -20
setrlimit 13 40 40
...
1.4 解析Service類型語句
init.rc中的Action星語句是ActionParser來進行解析,而Service由ServiceParser來進行解析。解析service,會用到兩個函數,一個是ParseSection,它會解析service的rc文件,比如上文講到的init.zygote64.rc,ParseSection函數主要用來搭建service的架子。另一個是ParseLineSection,用於解析子項。
1.5 init啓動zygote
Start方法
bool Service::Start() {
...
pid_t pid = fork();//1.fork函數創建子進程
if (pid == 0) {//2運行在子進程中
umask(077);
...
//3.通過execve執行程序
if (execve(args_[0].c_str(), (char**) &strs[0], (char**) ENV) < 0) {
ERROR("cannot execve('%s'): %s\n", args_[0].c_str(), strerror(errno));
}
_exit(127);
}
走到1處,子進程還沒被啓動。frok創建子進程,pid=0 說明在子線程中運行。3處service子進程就會被啓動,進入到service的main函數中。
frameworks/base/cmds/app_process/app_main.cpp
int main(int argc, char* const argv[])
{
...
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);//1
} 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;
}
}
1處的代碼可以得知調用runtime(AppRuntime)的start來啓動zygote。
1.6 屬性服務
屬性服務初始化與啓動
ystem/core/init/property_service.cpp
void property_init() {
if (__system_property_area_init()) {
ERROR("Failed to initialize property area\n");
exit(1);
}
}
void start_property_service() {
property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
0666, 0, 0, NULL);//1
if (property_set_fd == -1) {
ERROR("start_property_service socket creation failed: %s\n", strerror(errno));
exit(1);
}
listen(property_set_fd, 8);//2
register_epoll_handler(property_set_fd, handle_property_set_fd);//3
}
註釋1處用來創建非阻塞的socket。註釋2處調用listen函數對property_set_fd進行監聽,這樣創建的socket就成爲了server,也就是屬性服務;listen函數的第二個參數設置8意味着屬性服務最多可以同時爲8個試圖設置屬性的用戶提供服務。註釋3處的代碼將property_set_fd放入了epoll句柄中,用epoll來監聽property_set_fd:當property_set_fd中有數據到來時,init進程將用handle_property_set_fd函數進行處理。
在linux新的內核中,epoll用來替換select,epoll最大的好處在於它不會隨着監聽fd數目的增長而降低效率。因爲內核中的select實現是採用輪詢來處理的,輪詢的fd數目越多,自然耗時越多。
屬性服務處理請求
會調用handle_property_set_fd函數進行處理:
system/core/init/property_service.cpp
static void handle_property_set_fd()
{
...
handler_property_set(socket,prop_value,pro_value,true);//1
}
8.0在7.0做了進一步的判斷,普通屬性和控制屬性。
init進程總結
init進程主要做了三件事:
1.創建和掛載啓動所需的文件目錄
2.初始化和啓動屬性服務
3.解析init.rc配置文件並啓動zygote進程、
2、zygote進程啓動
1.Zygote簡介
在Android系統中,DVM(Dalvik虛擬機)和ART、應用程序進程以及運行系統的關鍵服務的SystemServer進程都是由Zygote進程來創建的,我們也將它稱爲孵化器。它通過fork
(複製進程)的形式來創建應用程序進程和SystemServer進程,由於Zygote進程在啓動時會創建DVM或者ART,因此通過fork而創建的應用程序進程和SystemServer進程可以在內部獲取一個DVM的實例拷貝。
啓動流程
2、Zygote進程總結
Zygote進程共做了如下幾件事:
1.創建AppRuntime並調用其start方法,啓動Zygote進程。
2.創建DVM併爲DVM註冊JNI.
3.通過JNI調用ZygoteInit的main函數進入Zygote的Java框架層。
4.通過registerZygoteSocket函數創建服務端Socket,並通過runSelectLoop函數等待ActivityManagerService的請求來創建新的應用程序進程。
5.啓動SystemServer進程。
3 SyetemServer進程啓動過程
1.Zygote啓動SyetemServer進程
frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
// 關閉 zygote進程創建的socket 該進程對systemserver沒用
zygoteServer.closeServerSocket();
handleSystemServerProcess(parsedArgs);
handleSystemServerProcess函數的代碼:
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = createSystemServerClassLoader(systemServerClasspath,
parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);//2
2處調用RuntimeInit的zygoteInit函數
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
nativeZygoteInit();//1啓動binder線程池
applicationInit(targetSdkVersion, argv, classLoader);//2進入systemServer的main方法
invokeStaticMain
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
...
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
通過反射返回的cl爲SystemServer類。找到SystemServer中的main函數。將找到的main函數傳入到MethodAndArgsCaller異常中並拋出該異常。截獲MethodAndArgsCaller異常的代碼在ZygoteInit.java的main函數中
rameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static void main(String argv[]) {
...
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run();//1
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
在註釋1處調用了MethodAndArgsCaller的run函數:
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
} catch (IllegalAccessException ex) {
...
}
}
}
2 解析SyetemServer進程
SystemServer的main函數:
frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
main函數中只調用了SystemServer的run函數,如下所示。
private void run() {
...
System.loadLibrary("android_servers");//1
...
mSystemServiceManager = new SystemServiceManager(mSystemContext);//2
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();//3
startCoreServices();//4
startOtherServices();//5
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
...
}
3.總結SyetemServer進程
SyetemServer在啓動時做了如下工作:
1.啓動Binder線程池,這樣就可以與其他進程進行通信。
2.創建SystemServiceManager用於對系統的服務進行創建、啓動和生命週期管理。
3.啓動各種系統服務。
4 Launcher啓動過程與系統啓動流程
1.Launcher概述
launcher通俗的就是Android的系統的桌面。作用:
1、作爲Android系統的啓動器,用於啓動應用程序
2、作爲系統的桌面,用於顯示和管理應用程序的快捷圖標或者其他桌面組件
2.Launcher啓動流程
在systemServer 中startOtherServices函數,會調用ActivityManagerService的systemReady函數。
systemReady函數中調用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked函數:
3.Launcher中應用圖標顯示流程
Launcher的onCreate函數如下所示。
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
@Override
protected void onCreate(Bundle savedInstanceState) {
...
LauncherAppState app = LauncherAppState.getInstance();//1 獲取實例
mDeviceProfile = getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE ?
app.getInvariantDeviceProfile().landscapeProfile
: app.getInvariantDeviceProfile().portraitProfile;
mSharedPrefs = Utilities.getPrefs(this);
mIsSafeModeEnabled = getPackageManager().isSafeMode();
mModel = app.setLauncher(this);//2
....
if (!mRestoring) {
if (DISABLE_SYNCHRONOUS_BINDING_CURRENT_PAGE) {
mModel.startLoader(PagedView.INVALID_RESTORE_PAGE);//3
} else {
mModel.startLoader(mWorkspace.getRestorePage());
}
}
...
}
setluncher 處會調用LauncherModel的initialize函數:
在initialize函數中會將Callbacks,也就是傳入的Launcher 封裝成一個弱引用對象。因此我們得知mCallbacks變量指的就是封裝成弱引用對象的Launcher,這個mCallbacks後文會用到它。
再回到Launcher的onCreate函數,在註釋2處調用了LauncherModel的startLoader函數…
5.Android系統啓動流程
1.啓動電源以及系統啓動
當電源按下時引導芯片代碼開始從預定義的地方(固化在ROM)開始執行。加載引導程序Bootloader到RAM,然後執行。
2.引導程序BootLoader
引導程序BootLoader是在Android操作系統開始運行前的一個小程序,它的主要作用是把系統OS拉起來並運行。
3.Linux內核啓動
內核啓動時,設置緩存、被保護存儲器、計劃列表、加載驅動。當內核完成系統設置,它首先在系統文件中尋找init.rc文件,並啓動init進程。
4.init進程啓動
初始化和啓動屬性服務,並且啓動Zygote進程。
5.Zygote進程啓動
創建JavaVM併爲JavaVM註冊JNI,創建服務端Socket,啓動SystemServer進程。
6.SystemServer進程啓動
啓動Binder線程池和SystemServiceManager,並且啓動各種系統服務。
7.Launcher啓動
被SystemServer進程啓動的ActivityManagerService會啓動Launcher,Launcher啓動後會將已安裝應用的快捷圖標顯示到界面上。