Linux系統(tǒng)啟動流程
Linux啟動概述
android系統(tǒng)內(nèi)核實質(zhì)是使用了Linux的內(nèi)核,所以在談到android app啟動流程就必須先了解Linux啟動流程;當(dāng)們啟動Linux系統(tǒng)時,bootloader會加載linux內(nèi)核到內(nèi)存運(yùn)行,完成后會啟動系統(tǒng)的第一個進(jìn)程(init進(jìn)程),其完成后會主動創(chuàng)建許多(Daemon)守護(hù)進(jìn)程,保證一些服務(wù)能正常開啟,如usb daemon進(jìn)程,保證usb驅(qū)動服務(wù)正常運(yùn)行。
android相關(guān)概述
init進(jìn)程會創(chuàng)建android底層的一個Zygote進(jìn)程,Zygote進(jìn)程會初始化第一個VM虛擬器,并且加載android相關(guān)的framework和app所需要的資源,然后Zygote會開啟一個socket來監(jiān)聽外部請求,如果收到請求,會根據(jù)已有的VM孵化出一個新的VM和進(jìn)程;
隨后,Zygote會創(chuàng)建一個System Server進(jìn)程,此進(jìn)程會啟動android相關(guān)的所有核心服務(wù),如AMS(Activity Manager Service)和其他服務(wù)進(jìn)程等,至此,系統(tǒng)會啟動第一個App--Home進(jìn)程,Home進(jìn)程就是手機(jī)的桌面進(jìn)程。
啟動桌面上的app
1. 點擊桌面app icon -> home的onclick()方法 -> startActivity(Intent)
2. 通過Binder通信進(jìn)制,將此次啟動信息通知給ActivityManagerService,在service內(nèi)部會做如下操作:
a. 收集此次啟動的對象信息,并封裝在intent對象里面去 --- PackageManager的resolveIntent()方法
b. 驗證用戶是否有足夠的權(quán)限來啟動這個activity --- grantUriPermissionLocked()
c. 如果有權(quán)限,AMS就會啟動這個activity,如果這個activity的進(jìn)程ProcessRecord為null的話,就會為其創(chuàng)建一個新進(jìn)程;反之,則回去打開已經(jīng)存在的activity
接下來,就開始分析AMS如何具體的啟動activity
3. AMS創(chuàng)建進(jìn)程啟動app
AMS調(diào)用startProcessLocked()方法創(chuàng)建新進(jìn)程,并且通過socket通道傳遞請求給Zygote進(jìn)程,Zygote進(jìn)程會根據(jù)收到的請求孵化出一個自身,并調(diào)用ZygoteInit.main來實例化一個ActivityThead,ActivityThread的main方法就是作為app的起始入口。
4. ActivityThread的main入口是app的起始入口,它是app進(jìn)程的主線程,管理Activity和Application的啟動和生命周期的調(diào)用等等
ActivityThread啟動細(xì)節(jié)
兩個重要內(nèi)部類
ApplicationThread 和 H
1. main入口
public static void main(String[] args) {
//創(chuàng)建Looper對象, 創(chuàng)建MessageQueue對象
Looper.prepareMainLooper();
//創(chuàng)建自己的ActivityThread對象
ActivityThread thread = new ActivityThread();
thread.attach(false); // --- 這個很重要
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
//進(jìn)入消息循環(huán)
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
//applicationThread實質(zhì)是一個binder實例,將binder實例綁定到AMS
private void attach(boolean system) {
...
//獲得AMS(ActivityManagerService)實例, AMS的log tag: "ActivityManager"
IActivityManager mgr = ActivityManagerNative.getDefault();
//把ApplicationThread對象傳給AMS
mgr.attachApplication(mAppThread);
...
}
2. attachApplication綁定ApplicationThread,收集進(jìn)程的信息,并通過ApplicationThread的bindApplication接口跨進(jìn)程回傳此次新進(jìn)程信息給ActivityThread
public final class ActivityManagerService extends ActivityManagerNative {
...
public final void attachApplication(IApplicationThread thread) {
...
attachApplicationLocked(thread, callingPid);
...
}
...
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
....
//通過binder,跨進(jìn)程調(diào)用ApplicationThread的bindApplication()方法, 下面代碼邏輯重回ActivityThread.java
thread.bindApplication(processName, appInfo, providers,
app.instrumentationClass, profileFile, profileFd, profileAutoStop,
app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked());
....
}
}
這個時候還在Binder進(jìn)程中,利用Handler把消息傳回給ActivityThread
//ActivityThread.java
private class ApplicationThread extends Binder implements IApplicationThread{
...
public final void bindApplication(String processName,
ApplicationInfo appInfo, List<ProviderInfo> providers,
ComponentName instrumentationName, String profileFile,
ParcelFileDescriptor profileFd, boolean autoStopProfiler,
Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
IUiAutomationConnection instrumentationUiConnection, int debugMode,
boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
Bundle coreSettings) {
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableOpenGlTrace = enableOpenGlTrace;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfileFile = profileFile;
data.initProfileFd = profileFd;
data.initAutoStopProfiler = false;
//發(fā)消息
sendMessage(H.BIND_APPLICATION, data);
}
...
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
//通過mH把BIND_APPLICATION消息發(fā)給H處理
mH.sendMessage(msg);
}
...
}
3. ActivityThread的H接收消息并開啟逐步執(zhí)行Application的oncreate
收到BIND_APPLICATION消息后,創(chuàng)建Application對象以及上下文
//ActivityThread.java
public final class ActivityThread {
...
private void handleBindApplication(AppBindData data) {
...
//創(chuàng)建Instrumentation 對象
java.lang.ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
//創(chuàng)建app運(yùn)行時的上下文對象,并對其進(jìn)行初始化.
final ContextImpl appContext = new ContextImpl();
appContext.init(data.info, null, this);
//這里的data.info是LoadedApk類的對象
//在這里創(chuàng)建了上層開發(fā)者的代碼中所涉及的Applicaiton類的對象
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
...
//如果有ContentProvider的話, 先加載ContentProvider,后調(diào)用Application的onCreate()方法
List<ProviderInfo> providers = data.providers;
if (providers != null) {
installContentProviders(app, providers);
}
//調(diào)Application的生命周期函數(shù) onCreate()
mInstrumentation.callApplicationOnCreate(app);
}
...
private class H extends Handler {
...
public static final int BIND_APPLICATION = 110;
...
public void handleMessage(Message msg) {
switch (msg.what) {
...
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);//調(diào)用ActivityThread的handleBindApplication()方法處理
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
}
}
}
執(zhí)行application的oncreate方法
// LoadedApk.java
public final class LoadedApk {
...
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
Application app = null;
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
return app;
}
...
}
// Instrumentation.java
public class Instrumentation {
...
public void callApplicationOnCreate(Application app) {
app.onCreate();
}
...
}
至此,Application啟動流程完了;同理,啟動activity的流程大致相同;
activty啟動開始點在AMS的attachApplicationLocked方法內(nèi)部,即bindApplication發(fā)送Application后,就會開始準(zhǔn)備啟動Activity,依次調(diào)用mStackSupervisor.attachApplicationLocked(app), 在里面再調(diào)用realStartActivityLocked(), 里面再調(diào)用app.thread.scheduleLaunchActivity(), 也就是mAppThread的scheduleLaunchActivity(), 在ApplicationThread的scheduleLaunchActivity()內(nèi),發(fā)送一個"LAUNCH_ACTIVITY"消息, mH處理"LAUNCH_ACTIVITY"時調(diào)用handleLaunchActivity(), handleLaunchActivity()分兩步, 第一步調(diào)performLaunchActivity(),
創(chuàng)建Activity的對象, 依次調(diào)用它的onCreate(), onStart(). 第二步調(diào)handleResumeActivity(), 調(diào)用Activity對象的onResume().
至此, 應(yīng)用啟動的完整流程就分析完整了
手動總結(jié):

參考文章:
http://www.itdecent.cn/p/a1f40b39b3de
http://www.itdecent.cn/p/a5532ecc8377