怎么查在哪個(gè)網(wǎng)站做的備案如何進(jìn)行關(guān)鍵詞優(yōu)化工作
一、Android 啟動流程概括
按下電源鍵觸發(fā)開機(jī),從 ROM 加載引導(dǎo)程序 BootLoader 到 RAM 中,BootLoader 執(zhí)行啟動 Linux kernel,然后啟動第一個(gè)用戶進(jìn)程 init,init 進(jìn)程的工作包括掛載文件、創(chuàng)建文件目錄、設(shè)置 selinux 安全策略,解析 init.rc 腳本等。隨后 init 進(jìn)程會啟動 Zygote 進(jìn)程,Zygote 進(jìn)程做一些資源預(yù)加載的工作,并啟動 SystemServer 進(jìn)程。SystemServer 進(jìn)程作為 Socket 服務(wù)端,啟動包括 AMS、WMS、PMS 等 90 多個(gè)服務(wù)在內(nèi)的系統(tǒng)服務(wù)。在眾多服務(wù)啟動完畢后,AMS 會打開 Launcher 應(yīng)用的 Home Activity,進(jìn)入手機(jī)桌面。
附:kernel 的初始化流程(詳細(xì)代碼自行下載 linux kernel 源碼)
傳統(tǒng)的加載器包含兩個(gè)文件
init.s:初始化堆棧,調(diào)用 main.c 的 main() 函數(shù)
main.c:初始化硬件(主板、鬧鐘等),創(chuàng)建 linux 標(biāo)簽
當(dāng)內(nèi)核完成系統(tǒng)設(shè)置后,會在系統(tǒng)文件中尋找 init 文件。
Dir:kernel/common/init/main.c
(1)執(zhí)行 kernel_init() 函數(shù)
(2)啟動 /bin/init? 文件:try_to_run_init_process("/bin/init");
(3)try_to_run_init_process() ---> run_init_process()--->kernel_execve()
init/android.bp 中指明了 init 的入口函數(shù):init/main.cpp,隨后會執(zhí)行 main.cpp 中的 main 方法
二、init 進(jìn)程的啟動流程
Dir:system/core/init/main.cpp ---> main() 方法
FirstStageMain() ---- SetupSelinux() ---- SecondStageMain()
第一階段
FirstStageMain()
1、mount()--掛載文件、mkdir()--創(chuàng)建文件目錄
2、SetStdioToDevNull()--重定向標(biāo)準(zhǔn)輸入輸出
3、InitKernelLogging()--初始化內(nèi)核日志
4、啟動 setupSelinux
SetupSelinux()
配置安全策略 -- 對應(yīng)安卓的權(quán)限策略
第二階段
SecondStageMain()
1、初始化屬性系統(tǒng)
PropertyInit()
2、監(jiān)聽子進(jìn)程的終止信號,釋放資源,防止僵尸進(jìn)程
InstallSignalFdHandler(&epoll);
InstallInitNotifier(&epoll);
StartPropertyService(&property_fd);
3、匹配 linux 命令和實(shí)際執(zhí)行函數(shù)之間的關(guān)系
GetBuiltinFunctionMap()
4、解析 init.rc
LoadBootScripts(am, sm)-->CreateParser() //創(chuàng)建解析器-->//添加 rc 文件的解析組件 service、on、importparser.AddSectionParser("service", std::make_unique<ServiceParser>(&service_list, GetSubcontext(), std::nullopt));parser.AddSectionParser("on", std::make_unique<ActionParser>(&action_manager, GetSubcontext()));parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));-->//解析 rc 文件parser.ParseConfig("/system/etc/init/hw/init.rc");-->ParserConfigDir-->ParserConfigFile-->ParserConfigFile-->ParserData
5、While(true) 循環(huán)監(jiān)聽
?
auto pending_functions = epoll.Wait(epoll_timeout);
總結(jié):init 進(jìn)程處理的事情:
1、 掛載文件
2、設(shè)置 selinux -- 安全策略
3、開啟屬性服務(wù),注冊到 epoll 中
4、解析 init.rc
5、循環(huán)處理腳本,包括啟動 zygote
6、循環(huán)等待
?? ??? ??? ??? ?
啟動 Service 的過程
/system/core/rootdir/init.rc-->on nonencryptedclass_start main --> do_class_start(const BuiltinArguments& args)class_start late_start/system/core/init/builtins.cpp-->do_class_start(const BuiltinArguments& args)-->StartIfNotDisabled()/system/core/init/service.cpp-->StartIfNotDisabled()-->Start()
三、Zygote 啟動流程
1、觸發(fā) Zygote
Dir:/system/core/rootdir/init.rc
(1)init.rc 中引入的 zygote.rc 腳本
import /system/etc/init/hw/init.${ro.zygote}.rc
不同的 rc 配置文件對應(yīng)不同的啟動策略
根據(jù)不同廠商共有四個(gè)屬性:
init.zygote32.rc? -- 執(zhí)行 app_process
init.zygote64.rc --執(zhí)行 app_process64
init.zygote32_64.rc -- 啟動兩個(gè) zygote 進(jìn)程,名為 zygote 和 zygote_secondary,分別執(zhí)行 app_process32、app_process64
init.zygote64_32.rc -- -- 啟動兩個(gè) zygote 進(jìn)程,名為 zygote 和 zygote_secondary,分別執(zhí)行 app_process64、app_process32
(2)zygote 觸發(fā)時(shí)機(jī)
on late-init-->trigger zygote-starton zygote-start-->start zygoteDir:/system/core/init/init.cpp
if (bootmode == "charger") {am.QueueEventTrigger("charger");
} else {am.QueueEventTrigger("late-init");
}
附:app_process 位于手機(jī)系統(tǒng)的 bin 目錄下,在 AS File Explorer 中可以看到,app_process 會
讀取到 /frameworks/base/cmds/app_process/Android.bp 文件,然后執(zhí)行 app_main.cpp,
/frameworks/base/cmds/app_process/app_main.cpp 的 main 方法解析的參數(shù),則來源于 init.zygote.rc
2、Zygote 初始化
Dir:/frameworks/base/cmds/app_process/app_main.cpp
(1)main() 進(jìn)行參數(shù)解析【--zygote? --start-system-server】
if (strcmp(arg, "--zygote") == 0) {zygote = true;niceName = ZYGOTE_NICE_NAME;
}
if (zygote) {runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
}
(2)創(chuàng)建虛擬機(jī)及注冊 JNI
Dir:frameworks/base/core/jni/AndroidRuntime.cpp
startVm() -- 創(chuàng)建虛擬機(jī)
startReg() -- 注冊 JNI--> register_jni_procs(gRegJNI, NELEM(gRegJNI), env) //gRegJNI 是一個(gè) jni 數(shù)組對象env->CallStaticVoidMethod(startClass, startMeth, strArray); //startClass 即傳入的ZygoteInit//接下來就會執(zhí)行 ZygoteInit.java 的 main 方法,從 native 層進(jìn)入 java 層//JVM :虛擬機(jī),其實(shí)就是一塊代碼,負(fù)責(zé)實(shí)現(xiàn)內(nèi)存管理,因?yàn)槭?zygote 通過 fork 創(chuàng)建的進(jìn)程,所以每個(gè)進(jìn)程都擁有一個(gè)獨(dú)立的 JVM
3、Zygote 的 java 啟動
(1)預(yù)加載,加快 app 進(jìn)程的啟動
Dir:frameworks/base/core/java/com/android/internal/os/ZygoteInit.java -- main()
preload(bootTimingsTraceLog);
(1)bootTimingsTraceLog.traceBegin("PreloadClasses");
//preloadClassess 將framework.jar里的preloaded-classes 定義的所有class load到內(nèi)存里,preloaded-classes 編譯Android后可以在framework/base下找到。
//會加載手機(jī) system/etc/preloaded-classes 文件中記錄好的類文件
(2)preloadResources();
//preloadResources 將系統(tǒng)的Resource(不是在用戶apk里定義的resource)load到內(nèi)存。資源preload到Zygoted的進(jìn)程地址空間,所有fork的子進(jìn)程將共享這份空間而無需重新load, 這大大減少了應(yīng)用程序的啟動時(shí)間,但反過來增加了系統(tǒng)的啟動時(shí)間。通過對preload 類和資源數(shù)目進(jìn)行調(diào)整可以加快系統(tǒng)啟動。Preload也是Android啟動最耗時(shí)的部分之一
(2)通知 VM 進(jìn)行垃圾回收
//gc()必須在fork之前完成(接下來的StartSystemServer就會有fork操作),這樣將來被復(fù)制出來的子進(jìn)程才能有盡可能少的垃圾內(nèi)存沒有釋放
gcAndFinalize();
(3)創(chuàng)建 zygote 服務(wù)端,本質(zhì)上是一個(gè) socket
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
zygoteServer = new ZygoteServer(isPrimaryZygote);-->//frameworks/base/core/java/com/android/internal/os/ZygoteServer.javamZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);-->//frameworks/base/core/java/com/android/internal/os/Zygote.javareturn new LocalServerSocket(fd);
?
(4)創(chuàng)建 SystemServer 進(jìn)程
Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);ZygoteInit.java--forkSystemServer()-->Zygote.java--nativeForkSystemServer()-->com_android_internal_os_Zygote_nativeForkSystemServer.cpp【通過 JNI 的映射】-->pid_t pid = zygote::ForkCommon(env, true,fds_to_close,fds_to_ignore,true);-->pid_t pid = fork(); //最終調(diào)用 linux 的 fork()
(5)循環(huán)等待
caller = zygoteServer.runSelectLoop(abiList);
四、SystemServer 啟動流程
1、參數(shù)處理
//ZygoteInit.java
//在 handleSystemServerProcess() 中進(jìn)行 server 的初始化工作if (pid == 0) {if (hasSecondZygote(abiList)) {waitForSecondaryZygote(socketName);}zygoteServer.closeServerSocket();return handleSystemServerProcess(parsedArgs);
}//(1) prepareSystemServerProfile(systemServerClasspath);
//(2) 判斷fork args 中是否有 invokWith 參數(shù),如果有則進(jìn)行WrapperInit.execApplicationif (parsedArgs.mInvokeWith != null) {String[] args = parsedArgs.mRemainingArgs;// If we have a non-null system server class path, we'll have to duplicate the// existing arguments and append the classpath to it. ART will handle the classpath// correctly when we exec a new process.if (systemServerClasspath != null) {String[] amendedArgs = new String[args.length + 2];amendedArgs[0] = "-cp";amendedArgs[1] = systemServerClasspath;System.arraycopy(args, 0, amendedArgs, 2, args.length);args = amendedArgs;}WrapperInit.execApplication(parsedArgs.mInvokeWith,parsedArgs.mNiceName, parsedArgs.mTargetSdkVersion,VMRuntime.getCurrentInstructionSet(), null, args);throw new IllegalStateException("Unexpected return from WrapperInit.execApplication");} else {ClassLoader cl = getOrCreateSystemServerClassLoader();if (cl != null) {Thread.currentThread().setContextClassLoader(cl);}/** Pass the remaining arguments to SystemServer.*/return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mDisabledCompatChanges,parsedArgs.mRemainingArgs, cl);
}
2、初始化
(1) ZygoteInit
//ZygoteInit.javaZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,parsedArgs.mDisabledCompatChanges,parsedArgs.mRemainingArgs, cl);-->ZygoteInit.nativeZygoteInit();--> //JNIcom_android_internal_os_ZygoteInit_nativeZygoteInit-->//AndroidRuntime.cppgCurRuntime->onZygoteInit();-->//app_main.cppvirtual void onZygoteInit(){sp<ProcessState> proc = ProcessState::self();ALOGV("App process: starting thread pool.\n");//啟動一個(gè) Binder 線程池,用于 SystemServer 和其他線程的通信proc->startThreadPool();}
(2)applicationInit
//ZygoteInit.javareturn RuntimeInit.applicationInit(targetSdkVersion, disabledCompatChanges, argv,classLoader);-->//RuntimeInit.javareturn findStaticMain(args.startClass, args.startArgs, classLoader);-->//RuntimeInit.java; 通過反射找到SystemServer 的 main 方法m = cl.getMethod("main", new Class[] { String[].class });return new MethodAndArgsCaller(m, argv);//耗時(shí)操作通過線程完成,MethodAndArgsCaller 的 run 方法中執(zhí)行 mMethod.invoke(null, new Object[] {null, new Object[]{ mArgs });-->//SystemServer 的 main 方法執(zhí)行:public static void main(String[] args) {new SystemServer().run();}
五、SystemServer 執(zhí)行流程
1、初始化
(1)一些屬性的設(shè)置
(2)初始化上下文
// Initialize the system context.
createSystemContext();private void createSystemContext() {ActivityThread activityThread = ActivityThread.systemMain();mSystemContext = activityThread.getSystemContext();mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);final Context systemUiContext = activityThread.getSystemUiContext();systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
2、創(chuàng)建 SystemServiceManager
//初始化SystemServiceManager,用來管理啟動service,SystemServiceManager中封裝了啟動Service的startService方法啟動系統(tǒng)必要的Service
mSystemServiceManager = new SystemServiceManager(mSystemContext);
3、啟動一系列系統(tǒng)服務(wù)
try {t.traceBegin("StartServices");startBootstrapServices(t);startCoreServices(t);startOtherServices(t);startApexServices(t);
} catch (Throwable ex) {Slog.e("System", "******************************************");Slog.e("System", "************ Failure starting system services", ex);throw ex;
} finally {t.traceEnd(); // StartServices
}