主要流程
init進(jìn)程啟動過程
init進(jìn)程是Android系統(tǒng)中用戶空間的第一個進(jìn)程纪铺。進(jìn)程號為1颜价。
引入init進(jìn)程
第一步
當(dāng)電源按下時引導(dǎo)芯片代碼從預(yù)定的地方(固化為ROM中)開始執(zhí)行悼瘾。加載引導(dǎo)程序BootLoader到RAM中執(zhí)行。
第二步
BootLoader是在Android操作系統(tǒng)開始運行前的一個小程序齿诞,主要作用是把系統(tǒng)OS拉起來運行麻裳。
第三步
當(dāng)內(nèi)核完成系統(tǒng)設(shè)置后,在系統(tǒng)文件中尋找init.rc文件涨椒,并啟動init進(jìn)程摊鸡。
啟動init進(jìn)程就會執(zhí)行它的入口函數(shù)main,文件路徑為:system/core/init/init.cpp
int main(int argc, char** argv) {
......
if (is_first_stage) {
boot_clock::time_point start_time = boot_clock::now();
umask(0);
//創(chuàng)建和掛載啟動所需要的文件目錄
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
mkdir("/dev/pts", 0755);
mkdir("/dev/socket", 0755);
mount("devpts", "/dev/pts", "devpts", 0, NULL);
#define MAKE_STR(x) __STRING(x)
mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
chmod("/proc/cmdline", 0440);
gid_t groups[] = { AID_READPROC };
setgroups(arraysize(groups), groups);
mount("sysfs", "/sys", "sysfs", 0, NULL);
mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));
......
}
......
//對屬性服務(wù)進(jìn)行初始化
property_init();
......
epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (epoll_fd == -1) {
PLOG(ERROR) << "epoll_create1 failed";
exit(1);
}
//用于設(shè)置子進(jìn)程信號處理函數(shù)蚕冬,如果子進(jìn)程異常退出免猾,init進(jìn)程會調(diào)用該函
//數(shù)中設(shè)置的信號處理函數(shù)進(jìn)行處理。
signal_handler_init();
......
//啟動屬性服務(wù)
start_property_service();
......
if (bootscript.empty()) {
//解析init.rc配置文件
parser.ParseConfig("/init.rc");
parser.set_is_system_etc_init_loaded(
parser.ParseConfig("/system/etc/init"));
parser.set_is_vendor_etc_init_loaded(
parser.ParseConfig("/vendor/etc/init"));
parser.set_is_odm_etc_init_loaded(parser.ParseConfig("/odm/etc/init"));
}
......
while (true) {
......
if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
am.ExecuteOneCommand();
}
if (!(waiting_for_prop || ServiceManager::GetInstance().IsWaitingForExec())) {
//重啟死去的服務(wù)
restart_processes();
}
......
}
return 0;
}
從上述代碼中可以看出播瞳,init進(jìn)程主要做了三件事:
- 創(chuàng)建和掛載啟動所需的文件目錄掸刊。
啟動掛載了
tmpfs、devpts赢乓、proc忧侧、sysfs和selinuxfs
共5種文件系統(tǒng),這些是系統(tǒng)運行時目錄牌芋,也就是說只有在系統(tǒng)運行的時候才會存在蚓炬。
- 初始化和啟動屬性服務(wù)。
屬性服務(wù)類似Windows平臺上的注冊表管理器躺屁,注冊表中以key-value的形式來記錄用戶肯夏、軟件的一些使用信息。即使系統(tǒng)或軟件重啟犀暑,也能夠根據(jù)之前注冊表中的記錄驯击,進(jìn)行相應(yīng)的初始化工作。
- 解析
init.rc
文件耐亏,創(chuàng)建Zygote進(jìn)程徊都。
該文件的路徑為:
system/core/rootdir/init.rc
。它是一個非常重要的配置文件广辰,是由Android初始化語言編寫的腳本暇矫。Android8.0對該文件進(jìn)行來拆分主之,每個服務(wù)對應(yīng)一個rc文件,啟動Zygote的腳本在init.zygoteXX.rc
中定義李根,代表多少位處理器槽奕。這里以64位為例。
system/core/rootdir/init.zygote64.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
group root readproc
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
onrestart restart wificond
writepid /dev/cpuset/foreground/tasks
這里我們只分析zygote進(jìn)程的創(chuàng)建房轿,所以只貼出了
init.rc
文件中的Serivice類型的語句粤攒,省略了其他語句;這是由Android初始化語言編寫的冀续。它的格式如下:
service <name> <pathname> [ <argument> ]*
//名字 執(zhí)行程序路徑 傳遞參數(shù)
< option >
//修飾詞琼讽,影響什么時候啟動,如何啟動service洪唐。
< option >
......
上面的代碼的含義就是:通知init進(jìn)程創(chuàng)建名為zygote的進(jìn)程,這個進(jìn)程的執(zhí)行路徑為:/system/bin/app/_process64
吼蚁,其后面的代碼是傳遞給app_process64
的參數(shù)凭需。class main
指的是zygote的classname為main。
init.rc
中的Service類型的語句有相應(yīng)的類來進(jìn)行解析肝匆,Service語句采用ServiceParser來進(jìn)行解析粒蜈,該實現(xiàn)代碼在system/core/init/service.app
中,代碼在這不再貼出旗国,大概的解析過程就是:根據(jù)參數(shù)創(chuàng)建出Service對象枯怖,然后根據(jù)選項域中的內(nèi)容填充Service對象,最后將該對象加入vector類型的Service鏈表中能曾。
在init.rc
中有如下代碼:
......
on nonencrypted
class_start main
class_start late_start
......
class_start是Android初始化語言中的Command類型的語句度硝,對應(yīng)的函數(shù)為
do_class_start
,含義就是啟動classname為main的Service寿冕。蕊程,從上述代碼我們知道zygote的classname
為main。
do_class_start
函數(shù)是在system/core/bin/builtins.cpp
中驼唱,代碼如下:
static int do_class_start(const std::vector<std::string>& args) {
ServiceManager::GetInstance().
ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });
return 0;
}
ForEachServiceInClass
函數(shù)會遍歷Service鏈表藻茂,找到classname
為main的Zygote,并執(zhí)行StartIfNotDisabled ()
函數(shù)玫恳。
StartIfNotDisabled ()
函數(shù)的代碼是在system/core/init/service.cpp
中定義的辨赐,代碼如下:
bool Service::StartIfNotDisabled() {
if (!(flags_ & SVC_DISABLED)) {
return Start();
} else {
flags_ |= SVC_DISABLED_START;
}
return true;
}
如果Service沒有在其對應(yīng)的
rc文件
中設(shè)置disabled選項,就會執(zhí)行Start()
函數(shù)京办,Zygote對應(yīng)的文件沒有設(shè)置disabled選項掀序。
Start()
函數(shù):system/core/init/service.cpp
bool Service::Start() {
flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
//如果已運行,直接返回
if (flags_ & SVC_RUNNING) {
return false;
}
......
struct stat sb;
//判斷需要啟動的Service對應(yīng)的執(zhí)行文件是否存在臂港,存在才會執(zhí)行森枪。
if (stat(args_[0].c_str(), &sb) == -1) {
PLOG(ERROR) << "cannot find '" << args_[0] << "', disabling '" << name_ << "'";
flags_ |= SVC_DISABLED;
return false;
}
......
pid_t pid = -1;
if (namespace_flags_) {
pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);
} else {
//如果沒有啟動视搏,調(diào)用fork函數(shù)創(chuàng)建子進(jìn)程
pid = fork();
}
if (pid == 0) {
umask(077);
......
//調(diào)用execve函數(shù),子進(jìn)程就會被啟動
if (execve(strs[0], (char**) &strs[0], (char**) ENV) < 0) {
PLOG(ERROR) << "cannot execve('" << strs[0] << "')";
}
_exit(127);
}
......
return true;
}
調(diào)用
execve 函數(shù)
县袱,子進(jìn)程就會被啟動浑娜,就是執(zhí)行對應(yīng)的main函數(shù)
,Zygote的執(zhí)行路徑為:system/bin/app_process64
式散,對應(yīng)的文件為app_main.cpp
筋遭。
frameworks/base/cmds/app_process/app_main.cpp
:
int main(int argc, char* const argv[])
{
......
while (i < argc) {
const char* arg = argv[i++];
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
} else if (strcmp(arg, "--start-system-server") == 0) {
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;
}
}
......
if (zygote) {
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.");
}
}
調(diào)用
runtime.start
函數(shù)就啟動了Zygote進(jìn)程。
Zygote進(jìn)程
在Android系統(tǒng)中暴拄,DVM和ART漓滔、應(yīng)用程序進(jìn)程以及運行系統(tǒng)的關(guān)鍵服務(wù)SystemServer進(jìn)程都是有Zygote進(jìn)程創(chuàng)建的,我們也稱它為孵化器乖篷。它通過fock(復(fù)制進(jìn)程)的形式來創(chuàng)建應(yīng)用程序進(jìn)程和SystemServer進(jìn)程响驴,由于Zygote進(jìn)程在啟動的時候會創(chuàng)建DVM或者ART,因此通過fock而創(chuàng)建的應(yīng)用程序進(jìn)程和SystemServer進(jìn)程可以在內(nèi)部獲取一個DVM或者ART的實例副本(也就是說一個Android應(yīng)用程序?qū)?yīng)這一個DVM或者ART)撕蔼。
Zygote進(jìn)程都是通過fock自身來創(chuàng)建子進(jìn)程的豁鲤,這樣Zygote進(jìn)程以及子進(jìn)程都會進(jìn)入
app_main.cpp
的main函數(shù),所以在上述代碼中先區(qū)分來當(dāng)前運行在哪個進(jìn)程中鲸沮。運行Zygote進(jìn)程就會執(zhí)行AndroidRuntime.start函數(shù)
琳骡。
frameworks/base/core/jni/AndroidRuntime.cpp
代碼如下:
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
......
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
//啟動Java虛擬機(jī)
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
//為JVM注冊JNI方法
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
......
//從app_main傳過來的參數(shù)classname值為:“com.android.internal.os.ZygoteInit”
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);
}
//將classname的“.”替換成“/”
char* slashClassName = toSlashClassName(className);
//找到ZygoteInit
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
} else {
//找到ZygoteInit的main函數(shù)
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
} else {
//通過JNI調(diào)用ZygoteInit的main函數(shù)
env->CallStaticVoidMethod(startClass, startMeth, strArray);
#if 0
if (env->ExceptionCheck())
threadExitUncaughtException(env);
#endif
}
}
......
}
上述代碼最后會調(diào)用ZygoteInit的
main方法
,該方法是由Java語言編寫的讼溺,當(dāng)前的運行邏輯在Native中楣号,這就需要通過JNI來調(diào)用Java。這樣Zygote就從Native層近入了Java框架層怒坯。
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
的main方法代碼如下:
public static void main(String argv[]) {
......
try {
......
//創(chuàng)建一個Server端的socket炫狱,socketName = “zygote”
//在這個socket上會等待AMS的請求
zygoteServer.registerServerSocket(socketName);
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
//預(yù)加載類和資源
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
//啟動SystemServer進(jìn)程
if (startSystemServer) {
startSystemServer(abiList, socketName, zygoteServer);
}
//等待AMS請求,里面是一個while(true)循環(huán)
zygoteServer.runSelectLoop(abiList);
zygoteServer.closeServerSocket();
}......
}
該方法中主要做了4件事:
1.創(chuàng)建一個Server端的socket(LocalServerSocket)敬肚。
2.預(yù)加載類和資源毕荐。
3.啟動SystemServer進(jìn)程。
4.等待AMS請求創(chuàng)建新的應(yīng)用程序進(jìn)程艳馒。
從上面的代碼我們看出Zygote進(jìn)程主要做了如下幾件事情:
- 1.創(chuàng)建Java虛擬機(jī)并為Java虛擬機(jī)注冊JNI方法憎亚。
- 2.通過JNI調(diào)用ZygoteInit的
main函數(shù)
進(jìn)入Zygote的Java框架層。 - 3.通過
registerServerSocket 方法
創(chuàng)建服務(wù)端Socket弄慰,并通過runSelectLoop 方法
等待AMS的請求來創(chuàng)建新的應(yīng)用程序進(jìn)程第美。 - 4.啟動SystemServer進(jìn)程。
SystemServer進(jìn)程
SystemServer進(jìn)程主要用于創(chuàng)建系統(tǒng)服務(wù)陆爽,AMS什往、WMS、PMS都是由它來創(chuàng)建的慌闭。從上面得知通過調(diào)用ZygoteInit的startSystemServer 方法
來啟動SystemServer進(jìn)程别威,下面就看一下該方法的代碼:
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
throws Zygote.MethodAndArgsCaller, RuntimeException {
......
//創(chuàng)建args數(shù)組躯舔,該數(shù)組用來保存啟動SystemServer的啟動參數(shù)
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
"--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);
//創(chuàng)建一個子進(jìn)程,也就是SystemServer進(jìn)程
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
//當(dāng)前代碼運行在子進(jìn)程中省古,也就是SystemServer進(jìn)程
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
//SystemServer進(jìn)程復(fù)制了Zygote進(jìn)程的地址空間粥庄,因此也會得到Zygote創(chuàng)建的Socket。
//該Socket對SystemServer進(jìn)程沒有用豺妓,所以要關(guān)閉惜互。
zygoteServer.closeServerSocket();
//處理SystemServer進(jìn)程
handleSystemServerProcess(parsedArgs);
}
return true;
}
從上面代碼可以看出,SystemServer進(jìn)程的用戶id和用戶組id被設(shè)置為1000琳拭,并且擁有1001~1010训堆、1018、1021白嘁、1032坑鱼、3001~3010的權(quán)限;進(jìn)程名字為
system_server
絮缅;啟動的類名為:com.android.server.SystemServer
姑躲。
創(chuàng)建出SystemServer進(jìn)程之后就會在該進(jìn)程調(diào)用ZygoteInit.handleSystemServerProcess 方法
,下面看一下該方法的代碼:
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws Zygote.MethodAndArgsCaller {
......
if (parsedArgs.invokeWith != null) {
......
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
//創(chuàng)建PathClassLoader
cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
//調(diào)用zygoteInit方法
ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
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();
//啟動Binder線程池
ZygoteInit.nativeZygoteInit();
//執(zhí)行SystemServer的main方法
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
在
zygoteInit方法
中創(chuàng)建了Binder線程池盟蚣,這樣SystemServer進(jìn)程就可以使用Binder于其他進(jìn)程進(jìn)行通信了。
創(chuàng)建Binder線程池后會調(diào)用RuntimeInit.applicationInit方法
卖怜,下面就接著看下該方法的代碼:
/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
......
// Remaining arguments are passed to the start class's static main
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller {
Class<?> cl;
try {
//通過反射得到SystemServer類
cl = Class.forName(className, true, classLoader);
}......
Method m;
try {
//找到SystemServer的main方法
m = cl.getMethod("main", new Class[] { String[].class });
}......
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.
*/
throw new Zygote.MethodAndArgsCaller(m, argv);
}
通過反射得到SystemServer屎开,className的值就是上面提到的
com.android.server.SystemServer
,然后再找到main方法
马靠,最后將main方法
傳入Zygote .MethodAndArgsCaller
異常中并拋出該異常奄抽。捕獲該異常的代碼在ZygoteInit.main方法
中,該main方法會調(diào)用SystemServer的main方法
甩鳄。
那為什么不直接在invokeStaticMain方法
中調(diào)用呢逞度?而是在異常捕獲中調(diào)用?
原因是異常處理會清楚所有設(shè)置過程中需要的堆棧幀妙啃,讓SystemServer的
main方法
看起來像是SystemServer進(jìn)程的入口档泽。(在Zygote
啟動SystemServer進(jìn)程之后,SystemServer進(jìn)程做了很多準(zhǔn)備工作揖赴,這些工作都是在main方法
調(diào)用之前做的馆匿。)
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
的main方法代碼:
public static void main(String argv[]) {
......
try {
......
//捕獲MethodAndArgsCaller異常
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket();
throw ex;
}
}
在異常處理中直接調(diào)用Zygote.MethodAndArgsCaller的
run方法
,可以看出MethodAndArgsCaller是Zygote的靜態(tài)內(nèi)部類燥滑。
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
public static class MethodAndArgsCaller extends Exception
implements Runnable {
......
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
......
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs });
}......
}
}
此處的
mMethod
就是SystemServer的main方法
渐北。
這樣就進(jìn)入了SystemServer的main方法
:
/frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
......
//創(chuàng)建Looper
Looper.prepareMainLooper();
//加載動態(tài)庫“l(fā)ibandroid_servers.so”
System.loadLibrary("android_servers");
performPendingShutdown();
//創(chuàng)建系統(tǒng)的上下文Context
createSystemContext();
// 創(chuàng)建SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}
// Start services.
try {
traceBeginAndSlog("StartServices");
//啟動引導(dǎo)服務(wù)
startBootstrapServices();
//啟動核心服務(wù)
startCoreServices();
//啟動其他服務(wù)
startOtherServices();
SystemServerInitThreadPool.shutdown();
}......
}
通過上面可以看出系統(tǒng)服務(wù)分為三種:
1.引導(dǎo)服務(wù)。
2.核心服務(wù)铭拧。
3.其他服務(wù)赃蛛。
private void startBootstrapServices() {
......
Installer installer = mSystemServiceManager.startService(Installer.class);
......
mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
......
//需要注意的是 ActivityManagerService.Lifecycle實現(xiàn)了SystemService
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
......
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
......
//在該方法中會把ActivityManagerService添加到ServiceManager中
mActivityManagerService.setSystemProcess();
......
}
private void startCoreServices() {
......
mSystemServiceManager.startService(DropBoxManagerService.class);
traceEnd();
......
mSystemServiceManager.startService(BatteryService.class);
......
}
private void startOtherServices() {
......
mSystemServiceManager.startService(KeyChainSystemService.class);
......
mSystemServiceManager.startService(TelecomLoaderService.class);
......
}
部分服務(wù)表:
引導(dǎo)服務(wù) | 作用 |
---|---|
Installer | 系統(tǒng)安裝APK時的一個服務(wù)恃锉,啟動完成Installer服務(wù)之后才能啟動其他的服務(wù) |
ActivityManagerService | 負(fù)責(zé)四大組件的啟動、切換和調(diào)度 |
PowerManagerService | 計算系統(tǒng)中和Power相關(guān)的計算呕臂,然后決策系統(tǒng)應(yīng)該如何反應(yīng) |
LightsService | 管理和顯示背光LED |
DisplayManagerService | 用來管理所有顯示的設(shè)備 |
UserManagerService | 多用戶模式管理 |
SensorService | 為系統(tǒng)提供各種感應(yīng)器服務(wù) |
PackageManagerService | 用來對APK進(jìn)行安破托、解析、刪除诵闭、卸載等操作 |
...... | ..... |
核心服務(wù) | |
DropBoxManagerService | 用于生成和管理系統(tǒng)運行時的一些日志文件 |
BatteryService | 管理電池相關(guān)的服務(wù) |
UsageStatsService | 收集用戶使用每一個app的頻率炼团、使用時長 |
WebViewUpdateService | WebView更新服務(wù) |
其他服務(wù) | |
CameraService | 攝像頭相關(guān)服務(wù) |
AlarmManagerService | 全局定時器管理服務(wù) |
InputManagerService | 管理輸入事件 |
WindowManagerService | 窗口管理服務(wù) |
VrManagerService | VR模式管理服務(wù) |
BluetoothService | 藍(lán)牙管理服務(wù) |
NotificationManagerService | 通知管理服務(wù) |
DeviceStorageMonitorService | 存儲相關(guān)管理服務(wù) |
LocationManagerService | 定位管理服務(wù) |
AudioService | 音頻相關(guān)管理服務(wù) |
...... | ...... |
我們從上面看出相關(guān)的服務(wù)一種是通過SystemServiceManager的startService方法
來啟動的;另一種是直接調(diào)用服務(wù)的main方法
疏尿,比如:PackageManagerService瘟芝。下面分別看一下這兩種方式的代碼實現(xiàn):
/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
public class SystemServiceManager {
......
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
......
//startService方法有幾個重載,最終都會調(diào)用該方法
public void startService(@NonNull final SystemService service) {
//注冊服務(wù)
mServices.add(service);
// Start it.
long time = System.currentTimeMillis();
try {
//調(diào)用服務(wù)自身的onStart方法
service.onStart();
}......
}
}
public abstract class SystemService {
......
}
先將服務(wù)添加到mService中褥琐,它是一個存儲SystemService類型的ArrayList锌俱,這樣就完成來該服務(wù)的注冊工作。然后調(diào)用服務(wù)自身的
onStart()方法
來啟動服務(wù)敌呈。由SystemServiceManager創(chuàng)建并啟動的服務(wù)贸宏,都是繼承了SystemService,但是并沒有實現(xiàn)IBinder磕洪,所以是不可以進(jìn)行Binder通信的吭练,也就是由它管理的服務(wù)是用于進(jìn)程內(nèi)部通信的。
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
public class PackageManagerService extends IPackageManager.Stub
implements PackageSender {
......
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
PackageManagerServiceCompilerMapping.checkProperties();
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
m.enableSystemUserPackages();
//注冊
ServiceManager.addService("package", m);
return m;
}
......
}
創(chuàng)建對象后添加到ServiceManager中析显,它是用來管理系統(tǒng)中各種Service的鲫咽,由它管理的服務(wù)都實現(xiàn)了IBinder,所以在ServiceManager中注冊的服務(wù)是用于進(jìn)程間通信的:用于系統(tǒng)C/S架構(gòu)中的Binder通信機(jī)制谷异》质客戶端要使用某個Service,需要先到ServiceManager中查詢Service的信息歹嘹,然后根據(jù)該信息與Service所在的Server進(jìn)程建立通信箩绍,這樣客戶端就可以使用Service了。
從上面的代碼我們看出SystemServer進(jìn)程主要做了如下幾件事情:
- 1.啟動Binder線程池尺上,這樣就可以與其他進(jìn)程進(jìn)行通信了材蛛。
- 2.創(chuàng)建SystemServiceManager,用于對系統(tǒng)其他服務(wù)進(jìn)行創(chuàng)建尖昏、啟動和聲明周期管理仰税。
- 3.啟動各種系統(tǒng)服務(wù)。
SystemServer進(jìn)程是Zygote進(jìn)程
fork
的第一個進(jìn)程抽诉。其中WindowManagerService陨簇、ActivityManagerService、PackageManagerService等重要的可以binder通信的服務(wù)都運行在這個SystemServer進(jìn)程。
Launcher啟動過程
系統(tǒng)啟動的最后一步就是啟動一個應(yīng)用程序來顯示系統(tǒng)中已經(jīng)安裝的應(yīng)用程序河绽,這個程序就叫做Launcher己单。它在啟動過程中會請求PackagerMangerService返回系統(tǒng)中已經(jīng)安裝的應(yīng)用程序信息,并將這些信息封裝成一個快捷圖標(biāo)列表顯示在系統(tǒng)屏幕上耙饰。這樣用戶就可以通過點擊快捷圖標(biāo)來啟動相應(yīng)的應(yīng)用程序了纹笼。
在上面SystemServer進(jìn)程分析過程中,我們知道ActivityManagerService(簡稱:AMS)是負(fù)責(zé)四大組件的啟動苟跪、切換和調(diào)度的廷痘。系統(tǒng)桌面本身也是一個Activity,所以Launcher的啟動是在AMS中進(jìn)行的件已,啟動Launcher的入口是AMS的systemReady方法
笋额。該方法是在SystemServer的startOtherServices方法
中被調(diào)用的,下面就看一下該方法的實現(xiàn)代碼:
private void startOtherServices(){
......
mActivityManagerService.systemReady(() -> {
Slog.i(TAG, "Making services ready");
traceBeginAndSlog("StartActivityManagerReadyPhase");
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
traceEnd();
traceBeginAndSlog("StartObservingNativeCrashes");
try {
mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
traceEnd();
......
}
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void systemReady(final Runnable goingCallback, BootTimingsTraceLog traceLog) {
......
synchronized (this) {
......
mStackSupervisor.resumeFocusedStackTopActivityLocked();
mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
......
}
}
該方法中調(diào)用了ActivityStackSupervisor的resumeFocusedStackTopActivityLocked()方法
篷扩。
/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
......
return false;
}
ActivityStack是用來描述Activity堆棧的兄猩。
最后經(jīng)過重重調(diào)用,最終會調(diào)用AMS的startHomeActivityLocked方法
鉴未。
boolean startHomeActivityLocked(int userId, String reason) {
//判斷系統(tǒng)的運行模式和mTopAction的值
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
return false;
}
獲取Luncher啟動所需要的Intent
Intent intent = getHomeIntent();
ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instr == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
final String myReason = reason + ":" + userId + ":" + resolvedUserId;
//啟動Luncher
mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
}
} else {
Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
}
return true;
}
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
mFactoryTest代表系統(tǒng)運行模式枢冤,運行模式有三種:非工廠模式、低級工廠模式和高級工廠模式铜秆;mTopAction表示第一個被啟動Activity組件的Action
淹真,它的默認(rèn)值為:Intent.ACTION_MAIN
。
在getHomeIntent方法
中连茧,如果mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL(低級工廠模式)
趟咆,Category的值為:Intent.CATEGORY_HOME
。也就是說如果系統(tǒng)運行模式不是低級工廠模式那么:
action = Intent.ACTION_MAIN
category = Intent.CATEGORY_HOME
而服務(wù)這個描述的應(yīng)用程序就是Luncher梅屉,因為Luncher的AndroidManifest
文件中的intent-filter
匹配了這兩個值:
/packages/apps/Launcher3/AndroidManifest.xml
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.launcher3">
<uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21"/>
......
<application
......
<activity
android:name="com.android.launcher3.Launcher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
android:enabled="true">
<intent-filter>
//匹配規(guī)則
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
<category android:name="android.intent.category.LAUNCHER_APP" />
</intent-filter>
</activity>
......
</application>
</manifest>
Luncher完成啟動后,作為桌面它會顯示應(yīng)用程序圖標(biāo)鳞贷。