android app啟動流程解析
Linux系統啟動流程
Linux啟動概述
android系統核心實質是使用了Linux的核心,所以在談到android app啟動流程就必須先了解Linux啟動流程;當們啟動Linux系統時,bootloader會載入linux核心到記憶體執行,完成後會啟動系統的第一個程式(init程式),其完成後會主動建立許多(Daemon)守護程式,保證一些服務能正常開啟,如usb daemon程式,保證usb驅動服務正常執行。
android相關概述
init程式會建立android底層的一個Zygote程式,Zygote程式會初始化第一個VM虛擬器,並且載入android相關的framework和app所需要的資源,然後Zygote會開啟一個socket來監聽外部請求,如果收到請求,會根據已有的VM孵化出一個新的VM和程式;
隨後,Zygote會建立一個System Server程式,此程式會啟動android相關的所有核心服務,如AMS(Activity Manager Service)和其他服務程式等,至此,系統會啟動第一個App--Home程式,Home程式就是手機的桌面程式。
啟動桌面上的app
1. 點選桌面app icon -> home的onclick()方法 -> startActivity(Intent)
2. 通過Binder通訊進位制,將此次啟動資訊通知給ActivityManagerService,在service內部會做如下操作:
a. 收集此次啟動的物件資訊,並封裝在intent物件裡面去 --- PackageManager的resolveIntent()方法
b. 驗證使用者是否有足夠的許可權來啟動這個activity --- grantUriPermissionLocked()
c. 如果有許可權,AMS就會啟動這個activity,如果這個activity的程式ProcessRecord為null的話,就會為其建立一個新程式;反之,則回去開啟已經存在的activity
接下來,就開始分析AMS如何具體的啟動activity
3. AMS建立程式啟動app
AMS呼叫startProcessLocked()方法建立新程式,並且通過socket通道傳遞請求給Zygote程式,Zygote程式會根據收到的請求孵化出一個自身,並呼叫ZygoteInit.main來例項化一個ActivityThead,ActivityThread的main方法就是作為app的起始入口。
4. ActivityThread的main入口是app的起始入口,它是app程式的主執行緒,管理Activity和Application的啟動和生命週期的呼叫等等
ActivityThread啟動細節
兩個重要內部類
ApplicationThread 和 H
1. main入口
public static void main(String[] args) {
//建立Looper物件, 建立MessageQueue物件
Looper.prepareMainLooper();
//建立自己的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"));
}
//進入訊息迴圈
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
//applicationThread實質是一個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,收集程式的資訊,並通過ApplicationThread的bindApplication介面跨程式回傳此次新程式資訊給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,跨程式呼叫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程式中,利用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;
//發訊息
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訊息發給H處理
mH.sendMessage(msg);
}
...
}
3. ActivityThread的H接收訊息並開啟逐步執行Application的oncreate
收到BIND_APPLICATION訊息後,建立Application物件以及上下文
//ActivityThread.java
public final class ActivityThread {
...
private void handleBindApplication(AppBindData data) {
...
//建立Instrumentation 物件
java.lang.ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
//建立app執行時的上下文物件,並對其進行初始化.
final ContextImpl appContext = new ContextImpl();
appContext.init(data.info, null, this);
//這裡的data.info是LoadedApk類的物件
//在這裡建立了上層開發者的程式碼中所涉及的Applicaiton類的物件
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
...
//如果有ContentProvider的話, 先載入ContentProvider,後呼叫Application的onCreate()方法
List<ProviderInfo> providers = data.providers;
if (providers != null) {
installContentProviders(app, providers);
}
//調Application的生命週期函式 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);//呼叫ActivityThread的handleBindApplication()方法處理
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
}
}
}
執行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方法內部,即bindApplication傳送Application後,就會開始準備啟動Activity,依次呼叫mStackSupervisor.attachApplicationLocked(app), 在裡面再呼叫realStartActivityLocked(), 裡面再呼叫app.thread.scheduleLaunchActivity(), 也就是mAppThread的scheduleLaunchActivity(), 在ApplicationThread的scheduleLaunchActivity()內,傳送一個"LAUNCH_ACTIVITY"訊息, mH處理"LAUNCH_ACTIVITY"時呼叫handleLaunchActivity(), handleLaunchActivity()分兩步, 第一步調performLaunchActivity(),
建立Activity的物件, 依次呼叫它的onCreate(), onStart(). 第二步調handleResumeActivity(), 呼叫Activity物件的onResume().
至此, 應用啟動的完整流程就分析完整了
手動總結:
參考文章:
http://www.jianshu.com/p/a1f40b39b3de
http://www.jianshu.com/p/a5532ecc8377
相關文章
- Android APP 冷啟動流程AndroidAPP
- Android App應用啟動流程(一)AndroidAPP
- Android系統啟動流程(二)解析Zygote程式AndroidGo
- App啟動流程APP
- 原始碼閱讀之Activity啟動與App啟動流程 – Android 9.0原始碼APPAndroid
- 原始碼閱讀之Activity啟動與App啟動流程 - Android 9.0原始碼APPAndroid
- FlutterEngin啟動流程&androidFlutterAndroid
- App 竟然是這樣跑起來的 —— Android App/Activity 啟動流程分析APPAndroid
- Android 系統啟動流程Android
- Android 9.0 init 啟動流程Android
- Android 應用啟動流程Android
- Android App啟動過程AndroidAPP
- NioEventLoop啟動流程原始碼解析OOP原始碼
- Android應用啟動流程分析Android
- Android系統啟動流程(四)Launcher啟動過程與系統啟動流程Android
- app啟動流程,activity啟動流程時序圖,binder相關資料APP時序圖
- SpringBoot原始碼解析-啟動流程(二)Spring Boot原始碼
- SpringBoot原始碼解析-啟動流程(一)Spring Boot原始碼
- Android Activity啟動流程原始碼分析Android原始碼
- Flutter Android 端啟動流程淺析FlutterAndroid
- Android原始碼分析:Activity啟動流程Android原始碼
- 深入理解Android 之 Activity啟動流程(Android 10)Android
- Activity 的 "啟動流程"(基於 Android 9.0)Android
- android app 啟動第一個頁面AndroidAPP
- [Android] Retrofit原始碼:流程解析Android原始碼
- Android系統原始碼分析--Service啟動流程Android原始碼
- Android系統原始碼分析–Service啟動流程Android原始碼
- 梳理一下Android 系統啟動流程Android
- 【Android】【init】解析init程式啟動過程Android
- iOS-APP的啟動流程和生命週期iOSAPP
- Android小知識-深入淺出Android系統啟動流程(上)Android
- Android小知識-深入淺出Android系統啟動流程(下)Android
- flutter在android端啟動流程和熱修復FlutterAndroid
- Android 系統原始碼-1:Android 系統啟動流程原始碼分析Android原始碼
- SpringSecurity啟動流程原始碼解析 | segmentfault新人第三彈SpringGse原始碼
- APP開啟(二)—標準流程APP
- iOS作業系統-- App啟動流程分析與優化iOS作業系統APP優化
- Android小知識-ActivityManagerService詳解(APP啟動過程)AndroidAPP
- 面試Tip:Android優化之APP啟動優化面試Android優化APP