Tip
本文主要介紹Android系統(tǒng)重啟動(dòng)到Home啟動(dòng)的過(guò)程,下面是本人整理的時(shí)序圖(由于圖片比較大,你們可以保存到本地放大看):
而下文也將對(duì)照時(shí)序圖的順序進(jìn)行分析笋熬。
Init進(jìn)程的啟動(dòng)
上圖是Linux系統(tǒng)的啟動(dòng)流程热某,而Android是基于Linux開(kāi)發(fā)的,所以也符合它的啟動(dòng)流程胳螟。我們可以看到Init進(jìn)程是由內(nèi)核系統(tǒng)fock出來(lái)的昔馋。該進(jìn)程的入口文件在
init.cpp#main(/system/core/init/init.cpp)
bool waiting_for_exec = false;
int main(int argc, char** argv) {
...
// 創(chuàng)建一些文件夾,并掛載設(shè)備糖耸,這些是和 Linux 相關(guān)的
if (is_first_stage) {
mount();
mkdir();
}
/*解析init.rc配置文件
*配置文件位于system/core/rootdir/init.rc中
*在解析配置文件中會(huì)啟動(dòng)zygote進(jìn)程
*/
init_parse_config_file("/init.rc");
...
while (true) {
if (!waiting_for_exec) {
execute_one_command();
restart_processes();
}
...
//阻塞 等待事件發(fā)生
int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));
}
}
init.cpp的main函數(shù)會(huì)先去解析init.rc配置文件秘遏,我們這里不深入分析,反正解析完配置文件以后嘉竟,我們會(huì)得到一個(gè)帶啟動(dòng)的進(jìn)程列表邦危,然后進(jìn)入死循環(huán)執(zhí)行啟動(dòng)進(jìn)程,那waiting_for_exec是在什么時(shí)候被置為true的呢舍扰?其實(shí)是在service_start()方法中倦蚪,下文會(huì)分析到,現(xiàn)在我們先略過(guò)边苹。
init.cpp#restart_processes
static void restart_processes()
{
process_needs_restart = 0;
service_for_each_flags(SVC_RESTARTING,
restart_service_if_needed);
}
其中service_for_each_flags的聲明在init.h中,實(shí)現(xiàn)在init_parse.cpp中:
init.h#service_for_each_flags
void service_for_each_flags(unsigned matchflags,void (*func)(struct service *svc));
init_parse.cpp#service_for_each_flags
void service_for_each_flags(unsigned matchflags,void (*func)(struct service *svc))
{
struct listnode *node;
struct service *svc;
list_for_each(node, &service_list) {
svc = node_to_item(node, struct service, slist);
if (svc->flags & matchflags) {
func(svc);
}
}
}
檢查service_list中的所有服務(wù)陵且,對(duì)于帶有SVC_RESTARTING標(biāo)志的服務(wù),則都會(huì)調(diào)用其相應(yīng)的restart_service_if_needed个束。
init.cpp#restart_service_if_needed
//如果有必要的話重啟服務(wù)
static void restart_service_if_needed(struct service *svc)
{
time_t next_start_time = svc->time_started + 5;
if (next_start_time <= gettime()) {
svc->flags &= (~SVC_RESTARTING);
//啟動(dòng)服務(wù)
service_start(svc, NULL);
return;
}
if ((next_start_time < process_needs_restart) ||
(process_needs_restart == 0)) {
process_needs_restart = next_start_time;
}
}
init.cpp#service_start
void service_start(struct service *svc, const char *dynamic_args)
{
...
//創(chuàng)建一個(gè)新的進(jìn)程
pid_t pid = fork();
...
//啟動(dòng)上文中新fork出來(lái)的進(jìn)程
execve(svc->args[0], (char**) arg_ptrs, (char**) ENV);
}
通過(guò)fork和execve我們會(huì)進(jìn)入app_main(zygote)進(jìn)程慕购。
階段總結(jié)
app_main(zygote)進(jìn)程的啟動(dòng)
該進(jìn)程的入口文件位于
app_main.cpp(/frameworks/base/cmds/app_process/app_main.cpp)
int main(int argc, char* const argv[])
{
...
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
if (strcmp(arg, "--zygote") == 0) {
zygote = true;
niceName = ZYGOTE_NICE_NAME;
}
...
if (zygote) {
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
} else if (className) {
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
} else {
...
}
}
當(dāng)我們的命令中包含--zygote的時(shí)候,我們就會(huì)調(diào)用到ZygoteInit播急。
AndroidRuntime.cpp#start(D:\Android\FrameworkSource\frameworks\base\core\jni)
...
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
//如果java虛擬機(jī)已經(jīng)被創(chuàng)建并啟動(dòng)則直接返回
if (startVm(&mJavaVM, &env, zygote) != 0) {
return;
}
onVmCreated(env);
/*
* Register android functions.
*/
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
...
//指明要調(diào)用的類脓钾,這里涉及到j(luò)ni調(diào)用
jclass startClass = env->FindClass(slashClassName);
...
//得到com.android.internal.os.ZygoteInit 的main方法的id
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
...
env->CallStaticVoidMethod(startClass, startMeth, strArray);
...
通過(guò)上文的JNI調(diào)用我們就進(jìn)入到Java的世界了
ZygoteInit#main(frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
//由app_main(zygote)進(jìn)程通過(guò)jni的方式調(diào)用
public static void main(String argv[]) {
...
try {
//注冊(cè)ZygoteSocket
registerZygoteSocket(socketName);
...
//預(yù)加載類和資源
preload();
...
if (startSystemServer) {
//啟動(dòng)SystemServer進(jìn)程,屬于行的進(jìn)程下文會(huì)詳細(xì)分析
startSystemServer(abiList, socketName);
}
runSelectLoop(abiList); //進(jìn)入循環(huán)模式
closeServerSocket();
...
} catch (MethodAndArgsCaller caller) {
caller.run();
}
}
registerZygoteSocket
private static void registerZygoteSocket(String socketName) {
if (sServerSocket == null) {
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
...
}
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc); //設(shè)置文件描述符
sServerSocket = new LocalServerSocket(fd); //創(chuàng)建Socket的本地服務(wù)端
} catch (IOException ex) {
...
}
}
}
preload
//預(yù)加載位于/system/etc/preloaded-classes文件中的類
preloadClasses();
//預(yù)加載資源桩警,包含drawable和color資源
preloadResources();
//預(yù)加載OpenGL
preloadOpenGL();
//通過(guò)System.loadLibrary()方法,
//預(yù)加載"android","compiler_rt","jnigraphics"這3個(gè)共享庫(kù)
preloadSharedLibraries();
//預(yù)加載 文本連接符資源
preloadTextResources();
//僅用于zygote進(jìn)程昌妹,用于內(nèi)存共享的進(jìn)程
WebViewFactory.prepareWebViewInZygote();
zygote進(jìn)程內(nèi)加載了preload()方法中的所有資源捶枢,當(dāng)需要fork新進(jìn)程時(shí)握截,采用copy on write技術(shù),如下:
startSystemServer(略過(guò)烂叔,下文會(huì)分析谨胞,屬于主流程)
runSelectLoop
private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
//sServerSocket是socket通信中的服務(wù)端,即zygote進(jìn)程蒜鸡。保存到fds[0]
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()];
for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
}
try {
//處理輪詢狀態(tài)胯努,當(dāng)pollFds有事件到來(lái)則往下執(zhí)行,否則阻塞在這里
Os.poll(pollFds, -1);
} catch (ErrnoException ex) {
...
}
for (int i = pollFds.length - 1; i >= 0; --i) {
//采用I/O多路復(fù)用機(jī)制逢防,當(dāng)接收到客戶端發(fā)出連接請(qǐng)求 或者數(shù)據(jù)處理請(qǐng)求到來(lái)叶沛,則往下執(zhí)行;
// 否則進(jìn)入continue忘朝,跳出本次循環(huán)灰署。
if ((pollFds[i].revents & POLLIN) == 0) {
continue;
}
if (i == 0) {
//即fds[0],代表的是sServerSocket局嘁,則意味著有客戶端連接請(qǐng)求溉箕;
// 則創(chuàng)建ZygoteConnection對(duì)象,并添加到fds。
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor()); //添加到fds.
} else {
//i>0悦昵,則代表通過(guò)socket接收來(lái)自對(duì)端的數(shù)據(jù)肴茄,并執(zhí)行相應(yīng)操作
boolean done = peers.get(i).runOnce();
if (done) {
peers.remove(i);
fds.remove(i); //處理完則從fds中移除該文件描述符
}
}
}
}
}
Zygote采用高效的I/O多路復(fù)用機(jī)制,保證在沒(méi)有客戶端連接請(qǐng)求或數(shù)據(jù)處理時(shí)休眠但指,否則響應(yīng)客戶端的請(qǐng)求独郎。
runOnce
boolean runOnce() throws ZygoteInit.MethodAndArgsCaller {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors;
try {
//讀取socket客戶端發(fā)送過(guò)來(lái)的參數(shù)列表
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
...
return true;
}
...
try {
//將binder客戶端傳遞過(guò)來(lái)的參數(shù),解析成Arguments對(duì)象格式
parsedArgs = new Arguments(args);
...
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
parsedArgs.appDataDir);
} catch (Exception e) {
...
}
try {
if (pid == 0) {
//子進(jìn)程執(zhí)行
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
//進(jìn)入子進(jìn)程流程
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
return true;
} else {
//父進(jìn)程執(zhí)行
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null;
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}
階段總結(jié)
Zygote啟動(dòng)過(guò)程的調(diào)用流程圖
1.解析init.zygote.rc中的參數(shù)枚赡,創(chuàng)建AppRuntime并調(diào)用AppRuntime.start()方法氓癌;
2.調(diào)用AndroidRuntime的startVM()方法創(chuàng)建虛擬機(jī),再調(diào)用startReg()注冊(cè)JNI函數(shù)贫橙;
3.通過(guò)JNI方式調(diào)用ZygoteInit.main()贪婉,第一次進(jìn)入Java世界;
4.registerZygoteSocket()建立socket通道卢肃,zygote作為通信的服務(wù)端疲迂,用于響應(yīng)客戶端請(qǐng)求;
5.preload()預(yù)加載通用類莫湘、drawable和color資源尤蒿、openGL以及共享庫(kù)以及WebView,用于提高app啟動(dòng)效率幅垮;
6.zygote完畢大部分工作腰池,接下來(lái)再通過(guò)startSystemServer(),fork得力幫手system_server進(jìn)程,也是上層framework的運(yùn)行載體示弓。
7.zygote功成身退讳侨,調(diào)用runSelectLoop(),隨時(shí)待命奏属,當(dāng)接收到請(qǐng)求創(chuàng)建新進(jìn)程請(qǐng)求時(shí)立即喚醒并執(zhí)行相應(yīng)工作跨跨。
最后,介紹給通過(guò)cmd命令囱皿,來(lái)fork新進(jìn)程來(lái)執(zhí)行類中main方法的方式:(啟動(dòng)后進(jìn)入RuntimeInit.main)
app_process [可選參數(shù)] 命令所在路徑 啟動(dòng)的類名 [可選參數(shù)]
SystemServer初始化
由上文可知勇婴,SystemServer由Zygote fork生成的,改進(jìn)程名為system_server,該進(jìn)程承載著framework的核心服務(wù)嘱腥。啟動(dòng)SystemServer起點(diǎn)是調(diào)用startSystemServer()耕渴,下面是system_server的啟動(dòng)流程:
上圖前4步驟(即顏色為紫色的流程)運(yùn)行在是Zygote進(jìn)程,從第5步(即顏色為藍(lán)色的流程)ZygoteInit.handleSystemServerProcess開(kāi)始是運(yùn)行在新創(chuàng)建的system_server爹橱,這是fork機(jī)制實(shí)現(xiàn)的(fork會(huì)返回2次)萨螺。
startSystemServer
startSystemServer會(huì)進(jìn)入開(kāi)啟SystemServer進(jìn)程階段,下文會(huì)詳細(xì)分析
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
...
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,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 {
//用于解析參數(shù)愧驱,生成目標(biāo)格式
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
// fork子進(jìn)程慰技,該進(jìn)程是system_server進(jìn)程【見(jiàn)小節(jié)2】
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
//進(jìn)入子進(jìn)程system_server
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
// 完成system_server進(jìn)程剩余的工作 【見(jiàn)小節(jié)5】
handleSystemServerProcess(parsedArgs);
}
return true;
}
startSystemServer函數(shù)主要的作用是準(zhǔn)備參數(shù)并fork新進(jìn)程,從上面可以看出system server進(jìn)程參數(shù)信息為uid=1000,gid=1000,進(jìn)程名為sytem_server组砚,從zygote進(jìn)程fork新進(jìn)程后吻商,需要關(guān)閉zygote原有的socket。另外糟红,對(duì)于有兩個(gè)zygote進(jìn)程情況艾帐,需等待第2個(gè)zygote創(chuàng)建完成。
forkSystemServer流程
Zygote.java(frameworks/base/core/java/com/android/internal/os/Zygote.java)#forkSystemServer
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork();
int pid = nativeForkSystemServer(
uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true);
}
VM_HOOKS.postForkCommon();
return pid;
}
nativeForkSystemServer()方法是本地方法在AndroidRuntime.cpp中注冊(cè)的盆偿,調(diào)用com_android_internal_os_Zygote.cpp中的register_com_android_internal_os_Zygote()方法建立native方法的映射關(guān)系柒爸。
nativeForkSystemServer(com_android_internal_os_Zygote.cpp)
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
jint debug_flags, jobjectArray rlimits, jlong permittedCapabilities,
jlong effectiveCapabilities) {
//fork子進(jìn)程
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
debug_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true, NULL,
NULL, NULL);
if (pid > 0) {
// zygote進(jìn)程,檢測(cè)system_server進(jìn)程是否創(chuàng)建
gSystemServerPid = pid;
int status;
if (waitpid(pid, &status, WNOHANG) == pid) {
//當(dāng)system_server進(jìn)程死亡后事扭,重啟zygote進(jìn)程
RuntimeAbort(env);
}
}
return pid;
}
當(dāng)system_server進(jìn)程創(chuàng)建失敗時(shí)捎稚,將會(huì)重啟zygote進(jìn)程。這里需要注意求橄,對(duì)于Android 5.0以上系統(tǒng)今野,有兩個(gè)zygote進(jìn)程,分別是zygote罐农、zygote64兩個(gè)進(jìn)程条霜,system_server的父進(jìn)程,一般來(lái)說(shuō)64位系統(tǒng)其父進(jìn)程是zygote64進(jìn)程涵亏。
1.當(dāng)kill system_server進(jìn)程后宰睡,只重啟zygote64和system_server蒲凶,不重啟zygote;
2.當(dāng)kill zygote64進(jìn)程后,只重啟zygote64和system_server夹厌,也不重啟zygote豹爹;
3.當(dāng)kill zygote進(jìn)程裆悄,則重啟zygote矛纹、zygote64以及system_server。
ForkAndSpecializeCommon
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids, jint debug_flags, jobjectArray javaRlimits, jlong permittedCapabilities, jlong effectiveCapabilities, jint mount_external, jstring java_se_info, jstring java_se_name, bool is_system_server, jintArray fdsToClose, jstring instructionSet, jstring dataDir) {
SetSigChldHandler(); //設(shè)置子進(jìn)程的signal信號(hào)處理函數(shù)
pid_t pid = fork(); //fork子進(jìn)程
if (pid == 0) {
//進(jìn)入子進(jìn)程
DetachDescriptors(env, fdsToClose); //關(guān)閉并清除文件描述符
if (!is_system_server) {
//對(duì)于非system_server子進(jìn)程光稼,則創(chuàng)建進(jìn)程組
int rc = createProcessGroup(uid, getpid());
}
SetGids(env, javaGids); //設(shè)置設(shè)置group
SetRLimits(env, javaRlimits); //設(shè)置資源limit
int rc = setresgid(gid, gid, gid);
rc = setresuid(uid, uid, uid);
SetCapabilities(env, permittedCapabilities, effectiveCapabilities);
SetSchedulerPolicy(env); //設(shè)置調(diào)度策略
//selinux上下文
rc = selinux_android_setcontext(uid, is_system_server, se_info_c_str, se_name_c_str);
if (se_info_c_str == NULL && is_system_server) {
se_name_c_str = "system_server";
}
if (se_info_c_str != NULL) {
SetThreadName(se_name_c_str); //設(shè)置線程名為system_server或南,方便調(diào)試
}
UnsetSigChldHandler(); //設(shè)置子進(jìn)程的signal信號(hào)處理函數(shù)為默認(rèn)函數(shù)
//等價(jià)于調(diào)用zygote.callPostForkChildHooks()
env->CallStaticVoidMethod(gZygoteClass, gCallPostForkChildHooks, debug_flags,
is_system_server ? NULL : instructionSet);
...
} else if (pid > 0) {
//進(jìn)入父進(jìn)程,即zygote進(jìn)程
}
return pid;
}
fork()創(chuàng)建新進(jìn)程艾君,采用copy on write方式采够,這是linux創(chuàng)建進(jìn)程的標(biāo)準(zhǔn)方法,會(huì)有兩次return,對(duì)于pid==0為子進(jìn)程的返回冰垄,對(duì)于pid>0為父進(jìn)程的返回蹬癌。 到此system_server進(jìn)程已完成了創(chuàng)建的所有工作,接下來(lái)開(kāi)始了system_server進(jìn)程的真正工作虹茶。在前面startSystemServer()方法中逝薪,zygote進(jìn)程執(zhí)行完forkSystemServer()后,新創(chuàng)建出來(lái)的system_server進(jìn)程便進(jìn)入handleSystemServerProcess()方法蝴罪。關(guān)于fork()董济,可查看理解Android進(jìn)程創(chuàng)建流程。
HandleSystemServerProcess流程
ZygoteInit.java#handleSystemServerProcess
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
...
//此處systemServerClasspath環(huán)境變量主要有/system/framework/目錄下的services.jar要门,ethernet-service.jar, wifi-service.jar這3個(gè)文件
final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
if (systemServerClasspath != null) {
//執(zhí)行dex優(yōu)化操作
performSystemServerDexOpt(systemServerClasspath);
}
//之前傳進(jìn)來(lái)的invokeWith為null虏肾,走eles邏輯
if (parsedArgs.invokeWith != null) {
String[] args = parsedArgs.remainingArgs;
if (systemServerClasspath != null) {
String[] amendedArgs = new String[args.length + 2];
amendedArgs[0] = "-cp";
amendedArgs[1] = systemServerClasspath;
System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
}
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
} else {
//通過(guò)類加載器加載指定目錄下的類并調(diào)用 RuntimeInit.zygoteInit
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
Thread.currentThread().setContextClassLoader(cl);
}
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
ZygoteInit.java#performSystemServerDexOpt
private static void performSystemServerDexOpt(String classPath) {
final String[] classPathElements = classPath.split(":");
//創(chuàng)建一個(gè)與installd的建立socket連接
final InstallerConnection installer = new InstallerConnection();
//執(zhí)行ping操作,直到與installd服務(wù)端連通為止
installer.waitForConnection();
final String instructionSet = VMRuntime.getRuntime().vmInstructionSet();
try {
for (String classPathElement : classPathElements) {
final int dexoptNeeded = DexFile.getDexOptNeeded(
classPathElement, "*", instructionSet, false /* defer */);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
//以system權(quán)限欢搜,執(zhí)行dex文件優(yōu)化
installer.dexopt(classPathElement, Process.SYSTEM_UID, false,
instructionSet, dexoptNeeded);
}
}
} catch (IOException ioe) {
throw new RuntimeException("Error starting system_server", ioe);
} finally {
installer.disconnect(); //斷開(kāi)與installd的socket連接
}
}
將classPath字符串中的apk封豪,分別進(jìn)行dex優(yōu)化操作。真正執(zhí)行優(yōu)化工作通過(guò)socket通信將相應(yīng)的命令參數(shù)炒瘟,發(fā)送給installd來(lái)完成吹埠。
zygoteInit流程
RuntimeInit#zygoteInit(frameworks/base/core/java/com/android/internal/os/RuntimeInit.java)
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application from zygote");
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "RuntimeInit");
//重定向日志
redirectLogStreams();
//通用組件初始化
commonInit();
//本地Zygote初始化 native方法
nativeZygoteInit();
//android第一個(gè)app應(yīng)用初始化
applicationInit(targetSdkVersion, argv, classLoader);
}
RuntimeInit#commonInit
private static final void commonInit() {
// 設(shè)置默認(rèn)的未捕捉異常處理方法
Thread.setDefaultUncaughtExceptionHandler(new UncaughtHandler());
// 設(shè)置市區(qū),中國(guó)時(shí)區(qū)為"Asia/Shanghai"
TimezoneGetter.setInstance(new TimezoneGetter() {
@Override
public String getId() {
return SystemProperties.get("persist.sys.timezone");
}
});
TimeZone.setDefault(null);
//重置log配置
LogManager.getLogManager().reset();
new AndroidConfig();
// 設(shè)置默認(rèn)的HTTP User-agent格式,用于 HttpURLConnection唧领。
String userAgent = getDefaultUserAgent();
System.setProperty("http.agent", userAgent);
// 設(shè)置socket的tag藻雌,用于網(wǎng)絡(luò)流量統(tǒng)計(jì)
NetworkManagementSocketTagger.install();
}
AndroidRuntime.cpp#com_android_internal_os_RuntimeInit_nativeZygoteInit
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz) {
//此處的gCurRuntime為AppRuntime,是在AndroidRuntime.cpp中定義的
gCurRuntime->onZygoteInit();
}
[–>app_main.cpp]
irtual void onZygoteInit() {
sp<ProcessState> proc = ProcessState::self();
proc->startThreadPool(); //啟動(dòng)新binder線程
}
ProcessState::self()是單例模式斩个,主要工作是調(diào)用open()打開(kāi)/dev/binder驅(qū)動(dòng)設(shè)備胯杭,再利用mmap()映射內(nèi)核的地址空間,將Binder驅(qū)動(dòng)的fd賦值ProcessState對(duì)象中的變量mDriverFD受啥,用于交互操作做个。startThreadPool()是創(chuàng)建一個(gè)新的binder線程鸽心,不斷進(jìn)行talkWithDriver(),在binder系列文章中的注冊(cè)服務(wù)(addService)詳細(xì)這兩個(gè)方法的執(zhí)行原理居暖。
RuntimeInit.java#applicationInit
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {
//true代表應(yīng)用程序退出時(shí)不調(diào)用AppRuntime.onExit()顽频,否則會(huì)在退出前調(diào)用
nativeSetExitWithoutCleanup(true);
//設(shè)置虛擬機(jī)的內(nèi)存利用率參數(shù)值為0.75
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args;
try {
args = new Arguments(argv); //解析參數(shù)
} catch (IllegalArgumentException ex) {
return;
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
//調(diào)用startClass的static方法 main()
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
RuntimeInit.java#invokeStaticMain
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller {
Class<?> cl = Class.forName(className, true, classLoader);
...
Method m;
try {
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))) {
...
}
//通過(guò)拋出異常,回到ZygoteInit.main()太闺。這樣做好處是能清空棧幀糯景,提高棧幀利用率。
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
還記得在zygote進(jìn)程的ZygoteInit.java的以下代碼嗎省骂?
public static void main(String argv[]) {
try {
startSystemServer(abiList, socketName);//啟動(dòng)system_server
....
} catch (MethodAndArgsCaller caller) {
caller.run(); //
} catch (RuntimeException ex) {
closeServerSocket();
throw ex;
}
}
很明顯當(dāng)我們拋出MethodAndArgsCaller異常時(shí)會(huì)調(diào)用 caller.run()方法蟀淮。
public static class MethodAndArgsCaller extends Exception implements Runnable {
public void run() {
try {
//根據(jù)傳遞過(guò)來(lái)的參數(shù),可知此處通過(guò)反射機(jī)制調(diào)用的是SystemServer.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);
}
}
}
代碼比較簡(jiǎn)單钞澳,就是通過(guò)反射調(diào)用SystemServer類的main()方法怠惶。
SystemServer啟動(dòng)(/frameworks/base/services/java/com/android/server/SystemServer.java)
SystemServer#main
public static void main(String[] args) {
//創(chuàng)建了一個(gè)SystemServer對(duì)象
new SystemServer().run();
}
SystemServer#run
private void run() {
//當(dāng)系統(tǒng)時(shí)間比1970年更早,就設(shè)置當(dāng)前系統(tǒng)時(shí)間為1970年
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
//變更虛擬機(jī)的庫(kù)文件轧粟,對(duì)于Android 6.0默認(rèn)采用的是libart.so
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
if (SamplingProfilerIntegration.isEnabled()) {
...
}
//清除vm內(nèi)存增長(zhǎng)上限策治,由于啟動(dòng)過(guò)程需要較多的虛擬機(jī)內(nèi)存空間
VMRuntime.getRuntime().clearGrowthLimit();
//設(shè)置內(nèi)存的可能有效使用率為0.8
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
// 針對(duì)部分設(shè)備依賴于運(yùn)行時(shí)就產(chǎn)生指紋信息,因此需要在開(kāi)機(jī)完成前已經(jīng)定義
Build.ensureFingerprintProperty();
//訪問(wèn)環(huán)境變量前兰吟,需要明確地指定用戶
Environment.setUserRequired(true);
//確保當(dāng)前系統(tǒng)進(jìn)程的binder調(diào)用通惫,總是運(yùn)行在前臺(tái)優(yōu)先級(jí)(foreground priority)
BinderInternal.disableBackgroundScheduling(true);
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
// 主線程looper就在當(dāng)前線程運(yùn)行
Looper.prepareMainLooper();
//加載android_servers.so庫(kù),該庫(kù)包含的源碼在frameworks/base/services/目錄下
System.loadLibrary("android_servers");
//檢測(cè)上次關(guān)機(jī)過(guò)程是否失敗揽祥,該方法可能不會(huì)返回
performPendingShutdown();
//初始化系統(tǒng)上下文
createSystemContext();
//創(chuàng)建系統(tǒng)服務(wù)管理
mSystemServiceManager = new SystemServiceManager(mSystemContext);
//將mSystemServiceManager添加到本地服務(wù)的成員sLocalServiceObjects
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
//啟動(dòng)各種系統(tǒng)服務(wù)
try {
startBootstrapServices(); // 啟動(dòng)引導(dǎo)服務(wù)
startCoreServices(); // 啟動(dòng)核心服務(wù)
startOtherServices(); // 啟動(dòng)其他服務(wù)
} catch (Throwable ex) {
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
//用于debug版本讽膏,將log事件不斷循環(huán)地輸出到dropbox(用于分析)
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
//一直循環(huán)執(zhí)行
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
LocalServices通過(guò)用靜態(tài)Map變量sLocalServiceObjects,來(lái)保存以服務(wù)類名為key拄丰,以具體服務(wù)對(duì)象為value的Map結(jié)構(gòu)府树。
SystemServer#performPendingShutdown
private void performPendingShutdown() {
final String shutdownAction = SystemProperties.get(
ShutdownThread.SHUTDOWN_ACTION_PROPERTY, "");
if (shutdownAction != null && shutdownAction.length() > 0) {
boolean reboot = (shutdownAction.charAt(0) == '1');
final String reason;
if (shutdownAction.length() > 1) {
reason = shutdownAction.substring(1, shutdownAction.length());
} else {
reason = null;
}
// 當(dāng)"sys.shutdown.requested"值不為空,則會(huì)重啟或者關(guān)機(jī)
ShutdownThread.rebootOrShutdown(null, reboot, reason);
}
}
SystemServer#createSystemContext
private void createSystemContext() {
//創(chuàng)建system_server進(jìn)程的上下文信息
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
//設(shè)置主題
mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}
理解Application創(chuàng)建過(guò)程已介紹過(guò)createSystemContext()過(guò)程, 該過(guò)程會(huì)創(chuàng)建對(duì)象有ActivityThread料按,Instrumentation, ContextImpl奄侠,LoadedApk,Application载矿。
SystemServer#startBootstrapServices
private void startBootstrapServices() {
//阻塞等待與installd建立socket通道
Installer installer = mSystemServiceManager.startService(Installer.class);
//啟動(dòng)服務(wù)ActivityManagerService
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
//啟動(dòng)服務(wù)PowerManagerService
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
//初始化power management
mActivityManagerService.initPowerManagement();
//啟動(dòng)服務(wù)LightsService
mSystemServiceManager.startService(LightsService.class);
//啟動(dòng)服務(wù)DisplayManagerService
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
//Phase100: 在初始化package manager之前垄潮,需要默認(rèn)的顯示.
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
//當(dāng)設(shè)備正在加密時(shí),僅運(yùn)行核心
String cryptState = SystemProperties.get("vold.decrypt");
if (ENCRYPTING_STATE.equals(cryptState)) {
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
mOnlyCore = true;
}
//啟動(dòng)服務(wù)PackageManagerService
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
//啟動(dòng)服務(wù)UserManagerService闷盔,新建目錄/data/user/
ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
AttributeCache.init(mSystemContext);
//設(shè)置AMS
mActivityManagerService.setSystemProcess();
//啟動(dòng)傳感器服務(wù)
startSensorService();
}
該方法創(chuàng)建的服務(wù)有:ActivityManagerService, PowerManagerService, LightsService, DisplayManagerService弯洗, PackageManagerService, UserManagerService逢勾, sensor服務(wù)牡整。
SystemServer#startCoreServices
private void startCoreServices() {
//啟動(dòng)服務(wù)BatteryService,用于統(tǒng)計(jì)電池電量溺拱,需要LightService.
mSystemServiceManager.startService(BatteryService.class);
//啟動(dòng)服務(wù)UsageStatsService逃贝,用于統(tǒng)計(jì)應(yīng)用使用情況
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();
//啟動(dòng)服務(wù)WebViewUpdateService
mSystemServiceManager.startService(WebViewUpdateService.class);
}
創(chuàng)建的服務(wù)有:BatteryService谣辞,UsageStatsService,WebViewUpdateService
SystemServer#startOtherServices
private void startOtherServices() {
...
SystemConfig.getInstance();
mContentResolver = context.getContentResolver(); // resolver
...
mActivityManagerService.installSystemProviders(); //provider
mSystemServiceManager.startService(AlarmManagerService.class); // alarm
// watchdog
watchdog.init(context, mActivityManagerService);
inputManager = new InputManagerService(context); // input
wm = WindowManagerService.main(...); // window
inputManager.start(); //啟動(dòng)input
mDisplayManagerService.windowManagerAndInputReady();
...
mSystemServiceManager.startService(MOUNT_SERVICE_CLASS); // mount
mPackageManagerService.performBootDexOpt(); // dexopt操作
ActivityManagerNative.getDefault().showBootMessage(...); //顯示啟動(dòng)界面
...
statusBar = new StatusBarManagerService(context, wm); //statusBar
//dropbox
ServiceManager.addService(Context.DROPBOX_SERVICE,
new DropBoxManagerService(context, new File("/data/system/dropbox")));
mSystemServiceManager.startService(JobSchedulerService.class); //JobScheduler
lockSettings.systemReady(); //lockSettings
//phase480 和phase500
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
...
// 準(zhǔn)備好window, power, package, display服務(wù)
wm.systemReady();
mPowerManagerService.systemReady(...);
mPackageManagerService.systemReady();
mDisplayManagerService.systemReady(...);
//下文會(huì)詳細(xì)分析
mActivityManagerService.systemReady(new Runnable() {
public void run() {
...
}
});
}
SystemServer啟動(dòng)各種服務(wù)中最后的一個(gè)環(huán)節(jié)便是AMS.systemReady()沐扳,詳見(jiàn)ActivityManagerService啟動(dòng)過(guò)程.
到此, System_server主線程的啟動(dòng)工作總算完成, 進(jìn)入Looper.loop()狀態(tài),等待其他線程通過(guò)handler發(fā)送消息到主線再處理泥从。
服務(wù)啟動(dòng)階段
關(guān)于服務(wù)啟動(dòng)階段的詳情請(qǐng)參考Android系統(tǒng)啟動(dòng)-SystemServer#服務(wù)啟動(dòng)階段部分
SystemServiceManager的startBootPhase()貫穿system_server進(jìn)程的整個(gè)啟動(dòng)過(guò)程
其中PHASE_BOOT_COMPLETED=1000,該階段是發(fā)生在Boot完成和home應(yīng)用啟動(dòng)完畢沪摄。系統(tǒng)服務(wù)更傾向于監(jiān)聽(tīng)該階段躯嫉,而不是注冊(cè)廣播ACTION_BOOT_COMPLETED,從而降低系統(tǒng)延遲卓起。
各個(gè)啟動(dòng)階段所在源碼的大致位置
public final class SystemServer {
private void startBootstrapServices() {
...
//phase100
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
...
}
private void startCoreServices() {
...
}
private void startOtherServices() {
...
//phase480 && 500
mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
...
mActivityManagerService.systemReady(new Runnable() {
public void run() {
//phase550
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
...
//phase600
mSystemServiceManager.startBootPhase(
SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
}
}
}
}
桌面應(yīng)用啟動(dòng)過(guò)程
通過(guò)上文我們知道當(dāng)所有的服務(wù)啟動(dòng)完成以后我們調(diào)用了 mActivityManagerService.systemReady(),下面我們進(jìn)入到其內(nèi)部看看做了哪些操作
ActivityManagerService#systemReady
public void systemReady(final Runnable goingCallback) {
synchronized(this) {
if (mSystemReady) {
// If we're done calling all the receivers, run the next "boot phase" passed in
// by the SystemServer
if (goingCallback != null) {
goingCallback.run();
}
return;
}
}
...
//啟動(dòng)桌面應(yīng)用程序
startHomeActivityLocked(mCurrentUserId, "systemReady");
...
}
ActivityManagerService#startHomeActivityLocked
boolean startHomeActivityLocked(int userId, String reason) {
...
Intent intent = getHomeIntent();
...
mStackSupervisor.startHomeActivity(intent, aInfo, reason);
...
}
Intent getHomeIntent() {
//通過(guò)隱式調(diào)用intent
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
<pre>
這里getHomeIntent加了一個(gè)Intent.CATEGORY_HOME的Category和敬,系統(tǒng)的Launcher這個(gè)Activity正好有這個(gè)android.intent.category.HOME的Category凹炸,這個(gè)文件在/packages/apps/Launcher2/AndroidManifest.xml
<application
android:name="com.android.launcher2.LauncherApplication"
android:label="@string/application_name"
android:icon="@mipmap/ic_launcher_home"
android:hardwareAccelerated="true"
android:largeHeap="@bool/config_largeHeap"
android:supportsRtl="true">
<activity
android:name="com.android.launcher2.Launcher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:resumeWhilePausing="true"
android:theme="@style/Theme"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="nosensor">
<intent-filter>
<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"/>
</intent-filter>
</activity>
</application>
所以這里是隱式的啟動(dòng)了Launcher戏阅,接著調(diào)用mStackSupervisor的startHomeActivity方法
ActivityStackSupervisor#startHomeActivity(/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java))
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
...
startActivityLocked(null /* caller */, intent, null /* resolvedType */, aInfo,
null /* voiceSession */, null /* voiceInteractor */, null /* resultTo */,
null /* resultWho */, 0 /* requestCode */, 0 /* callingPid */, 0 /* callingUid */,
null /* callingPackage */, 0 /* realCallingPid */, 0 /* realCallingUid */,
0 /* startFlags */, null /* options */, false /* ignoreTargetSecurity */,
false /* componentSpecified */,
null /* outActivity */, null /* container */, null /* inTask */);
}
這里調(diào)用了startActivityLocked方法,其實(shí)這個(gè)方法就是我們平時(shí)調(diào)用startActivity方法之后會(huì)調(diào)用的方法了啤它,至此桌面就被啟動(dòng)起來(lái)了奕筐。
總結(jié)
關(guān)于Android系統(tǒng)從開(kāi)機(jī)到啟動(dòng)桌面大概的過(guò)程如下:
1.啟動(dòng)linux內(nèi)核,fork第一個(gè)進(jìn)程init
2.init進(jìn)程解析init.rc文件变骡,然后fork出眾多進(jìn)程离赫,zygote進(jìn)程是其中之一
3.zygote進(jìn)程啟動(dòng)的虛擬機(jī),從C++環(huán)境切換到Java環(huán)境塌碌,并fork出system_server進(jìn)程
4.SystemServer啟動(dòng)眾多的系統(tǒng)Service如ActivityManagerService,WindowMangerService等
5.ActivityManagerService啟動(dòng)桌面Activity Luncher
參考
Android M系統(tǒng)啟動(dòng)流程
Android系統(tǒng)啟動(dòng)-概述
Android系統(tǒng)啟動(dòng)-Init篇
Android系統(tǒng)啟動(dòng)-zygote篇
Android系統(tǒng)啟動(dòng)-SystemServer上篇
Android系統(tǒng)啟動(dòng)-SystemServer下篇
深入理解init
深入理解 Zygote