Android 平臺(tái)的基礎(chǔ)是 Linux 內(nèi)核。Android Runtime (ART/Dalvik) 依靠 Linux 內(nèi)核來(lái)執(zhí)行底層功能,例如線程和低層內(nèi)存管理等。
而在Android Runtime之上就是我們經(jīng)常接觸的Java API Framework層, 如下圖是Android的系統(tǒng)架構(gòu)圖
今天的主題不是此架構(gòu)圖的各個(gè)部分解釋,而是離應(yīng)用層更近的Framework層啟動(dòng)過(guò)程分析。
如果我們這里拋開(kāi)Android架構(gòu)圖,那狹義的Framewrok主要包含那些內(nèi)容呢?
按我的理解,可以分為三個(gè)部分 服務(wù)端,客戶端,和依賴Linux底層能力的驅(qū)動(dòng)部分。
服務(wù)端
主要是ActivityManagerService(AMS), WindowManagerService(WMS),PackageM anerService(PMS)
還有用來(lái)處理觸摸消息的兩個(gè)類KeyInputQueue和InputDispatchThread,一個(gè)用來(lái)讀消息,一個(gè)用來(lái)分發(fā)消息.
客戶端
主要包括ActivityThread,Activity,DecodeView及父類View,PhoneWindow,ViewRootImpl及內(nèi)部類W等
依賴Linux底層能力的驅(qū)動(dòng)
主要是SurfaceFlingger(SF)和Binder驅(qū)動(dòng)
Zygote
系統(tǒng)中運(yùn)行的第一個(gè)Dalvik虛擬機(jī)程序叫做zygote,該名稱的意義是“一個(gè)卵”,,因?yàn)榻酉聛?lái)的所有 Dalvik虛擬機(jī)進(jìn)程都是通過(guò)這個(gè)“卵” 孵化出來(lái)的。
zygote進(jìn)程中包含兩個(gè)主要模塊,分別如下:
zygote進(jìn)程對(duì)應(yīng)的具體程序是app_rocess,該程序存在于system/bin目錄下,啟動(dòng)該程序的指令是 在 init.rc中進(jìn)行配置的。
Zygote 有?兩個(gè)優(yōu)秀的特點(diǎn)
SystemServer
zygote孵化出的第一個(gè)Dalvik進(jìn)程叫做SystemServer,SystemServer僅僅是該進(jìn)程的別名,而該進(jìn)程具體對(duì)應(yīng)的程序依然是app_process,因?yàn)镾ystemServer是從app_process中孵化出來(lái)的。
SystemServer中創(chuàng)建了一個(gè)Socket客戶端,并有AmS負(fù)責(zé)管理該客戶端,之后所有的Dalvik進(jìn)程都將通過(guò)該Socket客戶端間接被啟動(dòng)。當(dāng)需要啟動(dòng)新的APK進(jìn)程時(shí),AmS中會(huì)通過(guò)該Socket客戶端向 zygote進(jìn)程的Socket服務(wù)端發(fā)送一個(gè)啟動(dòng)命令,然 后 zygote會(huì)孵化出新的進(jìn)程。 上面提到的服務(wù)端,AMS,PMS,WMS等都是在SystemServer中啟動(dòng)的.
操作系統(tǒng)的一般啟動(dòng)流程,分為三個(gè)步驟
Android 系統(tǒng)是基于Linux 內(nèi)核Kernel,前面Linux bootloader這里不做介紹,直接介紹操作系統(tǒng)內(nèi)核初始化,在這個(gè)時(shí)候,它會(huì)加載init.rc文件.
init.rc文件
在Android根目錄下面,可以直接找到init.rc
generic_x86:/ # ls
acct bin cache config data dev init init.rc init.usb.rc lost+found mnt oem product sdcard sys ueventd.rc
adb_keys bugreports charger d default.prop etc init.environ.rc init.usb.configfs.rc init.zygote32.rc metadata odm proc sbin storage system vendor
打開(kāi)init.rc
generic_x86:/ # cat init.rc
# ..... 省略其他
# Now we can start zygote for devices with file based encryption
trigger zygote-start
# It is recommended to put unnecessary data/ initialization from post-fs-data
# to start-zygote in device's init.rc to unblock zygote start.
on zygote-start
# A/B update verifier that marks a successful boot.
exec_start update_verifier_nonencrypted
start netd
start zygote
start zygote_secondary
on property:vold.decrypt=trigger_restart_framework
stop surfaceflinger
# 啟動(dòng)SF
start surfaceflinger
# ..... 省略其他 media(媒體) network(網(wǎng)絡(luò))等啟動(dòng)
也就是在 init.rc時(shí),啟動(dòng)Android 內(nèi)核。
app_process
Android 內(nèi)核也是main方法開(kāi)始,他的main方法在 frameworks/base/cmds/app_process/app_main.cpp下
int main(int argc, char* const argv[])
{
...
//初始化AndroidRuntime
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
bool zygote = false;
bool startSystemServer = false;
bool application = false;
String8 niceName;
String8 className;
// 根據(jù)參數(shù)具體判斷啟動(dòng)那個(gè)服務(wù)
++i; // Skip unused "parent dir" argument.
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 (!className.isEmpty()) {
args.add(application ? String8("application") : String8("tool"));
runtime.setClassNameAndArgs(className, argc - i, argv + i);
}else{
....
//啟動(dòng)SystemServer
if (startSystemServer) {
args.add(String8("start-system-server"));
}
}
....
if (zygote) {
//啟動(dòng)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.");
}
}
在這個(gè)Main方法中,先初始化了AppRuntime,他的父類是AndroidRuntime。然后我們看到了啟動(dòng)了Java類ZygoteInit。
那c++代碼里怎么啟動(dòng)Java類呢,我們繼續(xù)看 start方法
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
...
//啟動(dòng)Java虛擬機(jī)
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
...
//找到Java 里面的Main方法
jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
"([Ljava/lang/String;)V");
if (startMeth == NULL) {
ALOGE("JavaVM unable to find main() in '%s'\n", className);
/* keep going */
} else {
//執(zhí)行Main方法
env->CallStaticVoidMethod(startClass, startMeth, strArray);
}
....
}
可以看到最后先創(chuàng)建了Java虛擬機(jī),調(diào)用了Java的main方法,是不是感覺(jué)有些熟悉感了。
上面介紹到,會(huì)啟動(dòng)Java的ZygoteInit類,那他里面干了些什么呢? 我們來(lái)看一下關(guān)鍵代碼,還是從Main方法開(kāi)始
//ZygoteInit.java
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer();
ZygoteHooks.startZygoteNoThreadCreation();
//創(chuàng)建socket
zygoteServer.createZygoteSocket(socketName);
Zygote.createBlastulaSocket(blastulaSocketName);
if (!enableLazyPreload) {
bootTimingsTraceLog.traceBegin("ZygotePreload");
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
//預(yù)加載系統(tǒng)資源
preload(bootTimingsTraceLog);
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
bootTimingsTraceLog.traceEnd(); // ZygotePreload
} else {
Zygote.resetNicePriority();
}
//fork SystemServer進(jìn)程
if (startSystemServer) {
Runnable r = forkSystemServer(abiList, socketName, zygoteServer);
// child (system_server) process.
if (r != null) {
r.run();
return;
}
}
//等待Socket的接入
if (caller == null) {
Log.i(TAG, "Accepting command socket connections");
// The select loop returns early in the child process after a fork and
// loops forever in the zygote.
caller = zygoteServer.runSelectLoop(abiList);
}
注釋寫(xiě)了大概Zygote 啟動(dòng)里面的初始化內(nèi)容
下面繼續(xù)看SystemServer 啟動(dòng)的過(guò)程,從Main方法開(kāi)始
//SystemServer.java
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
很簡(jiǎn)單,創(chuàng)建一個(gè)自己的對(duì)象,并執(zhí)行run方法,看一下run方法
private void run() {
...
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
VMRuntime.getRuntime().clearGrowthLimit();
// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
run方法里面主要進(jìn)行了設(shè)置手機(jī)時(shí)間,設(shè)置虛擬機(jī)內(nèi)存大小,創(chuàng)建消息循環(huán)Looper,創(chuàng)建SystemServiceManager等,最主要的是啟動(dòng)了各類服務(wù),我們接著看一下startBootstrapServices ,startCoreServices,startOtherServices方法
private void startBootstrapServices() {
Installer installer = mSystemServiceManager.startService(Installer.class);
mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
....
}
private void startCoreServices() {
...
mSystemServiceManager.startService(BatteryService.class);
...
}
private void startOtherServices() {
final Context context = mSystemContext;
VibratorService vibrator = null;
DynamicAndroidService dynamicAndroid = null;
IStorageManager storageManager = null;
NetworkManagementService networkManagement = null;
IpSecService ipSecService = null;
NetworkStatsService networkStats = null;
NetworkPolicyManagerService networkPolicy = null;
ConnectivityService connectivity = null;
NsdService serviceDiscovery= null;
WindowManagerService wm = null;
SerialService serial = null;
NetworkTimeUpdateService networkTimeUpdater = null;
InputManagerService inputManager = null;
TelephonyRegistry telephonyRegistry = null;
ConsumerIrService consumerIr = null;
MmsServiceBroker mmsService = null;
HardwarePropertiesManagerService hardwarePropertiesService = null;
....
}
在這些方法中啟動(dòng)了,我們的核心服務(wù),和常用服務(wù)。 代碼中也可以看到AMS,PMS,WMS等相關(guān)服務(wù).
一般服務(wù)啟動(dòng)完成后,就會(huì)想繼調(diào)用systemReady()方法。 在SysytemServer startOtherServices中看到一個(gè)監(jiān)聽(tīng)回調(diào)
mActivityManagerService.systemReady(() -> {
try {
startSystemUi(context, windowManagerF);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
}
}
static final void startSystemUi(Context context, WindowManagerService windowManager) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.SYSTEM);
windowManager.onSystemUiStarted();
}
而Ams啟動(dòng)完成后,顯示Launcher
//AMS.java
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
...
startHomeActivityLocked(currentUserId, "systemReady");
//
mStackSupervisor.resumeFocusedStackTopActivityLocked();
...
}
復(fù)制代碼
其實(shí)到這里大致流程就介紹完了,但是文章開(kāi)始的ActivityThread的main方法是何時(shí)被調(diào)用的,還沒(méi)回答,這里不詳細(xì)展開(kāi),簡(jiǎn)略回答一些.
ActivityThread的main方法如何被調(diào)用的?
AMS是管理Activity的啟動(dòng)結(jié)束等,查看AMS代碼,當(dāng)當(dāng)前啟動(dòng)的APP沒(méi)有創(chuàng)建進(jìn)程時(shí),會(huì)最終調(diào)用到ZygoteProcess,然后向 Zygote發(fā)送一個(gè)socket請(qǐng)求。
resumeTopActivityLocked -> startProcessLocked -> Process.start() -> ZygoteProcess.start() -> ZygoteProcess.startViaZygote() —> ZygoteProcess.zygoteSendArgsAndGetResult()
接下來(lái),看一下大致代碼
//AMS.java
private final boolean startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
//這里entryPoint為ActivityThread
final String entryPoint = "android.app.ActivityThread";
return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
startTime);
}
//ZygoteProcess.java
private Process.ProcessStartResult startViaZygote(final String processClass,... ){
ArrayList<String> argsForZygote = new ArrayList<String>();
argsForZygote.add("--runtime-args");
argsForZygote.add("--setuid=" + uid);
argsForZygote.add("--setgid=" + gid);
argsForZygote.add("--runtime-flags=" + runtimeFlags);
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
if (startChildZygote) {
argsForZygote.add("--start-child-zygote");
}
argsForZygote.add(processClass);
synchronized(mLock) {
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
useBlastulaPool,
argsForZygote);
}
}
//發(fā)起Socket請(qǐng)求,給Zygote
private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ArrayList<String> args,..){
blastulaSessionSocket = zygoteState.getBlastulaSessionSocket();
final BufferedWriter blastulaWriter = new BufferedWriter(
new OutputStreamWriter(blastulaSessionSocket.getOutputStream()),
Zygote.SOCKET_BUFFER_SIZE);
final DataInputStream blastulaReader =
new DataInputStream(blastulaSessionSocket.getInputStream());
blastulaWriter.write(msgStr);
blastulaWriter.flush();
...
}
最終 Zygote收到請(qǐng)求調(diào)用ZygoteInit中zygoteinit方法
//ZygoteInit.java
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
在 RuntimeInit中findStaticMain,最后在ZygoteInit中執(zhí)行最終返回的這個(gè)Runnable,達(dá)到調(diào)用main方法的目的.
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) {
nativeSetExitWithoutCleanup(true);
VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
final Arguments args = new Arguments(argv);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
return findStaticMain(args.startClass, args.startArgs, classLoader);
}
protected static Runnable findStaticMain(String className, String[] argv,
ClassLoader classLoader) {
..
m = cl.getMethod("main", new Class[] { String[].class });
return new MethodAndArgsCaller(m, argv);
}