
App 啟動流程分析
Android中每一個App都在一個獨立的空間,運作在一個單獨的程序中,擁有一個vm,系統會配置設定一個唯一的user ID 如
u0_a30
,用來實作沙盒目錄。
init程序會啟動一個"Zygote"程序. 這個程序初始化了第一個VM, 并且預加載了framework和衆多App所需要的通用資源. 然後它開啟一個Socket接口來監聽請求, 根據請求孵化出新的VM來管理新的App程序. 一旦收到新的請求, Zygote會基于自身預先加載的VM來孵化出一個新的VM建立一個新的程序. Zygote還會孵化出一個超級管理程序---System Server. SystemServer會啟動所有系統核心服務: 引導服務(7個):ActivityManagerService、PowerManagerService、LightsService、DisplayManagerService、PackageManagerService、UserManagerService、SensorService; 核心服務(3個):BatteryService、UsageStatsService、WebViewUpdateService; 其他服務(70個+):AlarmManagerService、VibratorService等。
啟動App流程
啟動一個App的方式
Intent intent = packageManager.getLaunchIntentForPackage(packname);
startActivity(intent);
或者
ComponentName cn = new ComponentName("com.example", "com.example.MainActivity");
startActivity(intent);
啟動一個應用時:都會調用startActivity(Intent)
Activity.startActivity
```
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
// 忽略...
// 這裡mMainThread也是Activity類的成員變量,它的類型是ActivityThread,
// token是表示Activity
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
// 忽略...
}
```
這裡mMainThread也是Activity類的成員變量,它的類型是ActivityThread,mMainThread.getApplicationThread獲得它裡面的ApplicationThread成員變量,這個ApplicationThread實際上是一個Binder對象,是App所在的程序與AMS所在程序system_server通信的橋梁。 1. AMS會對Activity生命周期的管理以及任務棧的管理,通過Binder通信,這時AMS是Server端,App程序持有AMS的client端IActivityManagerSingleton進行通信 2. AMS在完成任務棧和生命周期管理後,回調App方法,這時AMS是client持有App的ApplicationThread進行通信
mToken是Activity中一個成員變量,AMS和Activity互動中并沒有把Activity執行個體傳入,而是使用mToken,可以唯一标示Activity。
Instrumentation.execStartActivity
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
// Binder對象,把這個句柄傳給AMS,用來回調App程序方法
IApplicationThread whoThread = (IApplicationThread) contextThread;
// 忽略..
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
這裡把App中Binder的Server端的ApplicationThread的句柄傳給AMS,用于生命周期的回調等,如onPause。 通過Binder驅動,就進入過AMS的startActivity方法
ActivityManagerService 通知目前程序進入pause狀态
AMS在system_server程序中,由于AMS中代碼太多了,我們這裡就不全部展開講了,大概的說一下。有興趣的可以去看一下老羅的文章。 在AMS會新建立一個棧Task,并通過ApplicationThread的句柄通知目前Activity進入paused狀态
回到ActivityThread中
public final class ActivityThread {
// ......
private class ApplicationThread extends IApplicationThread.Stub {
// ......
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
int seq = getLifecycleSeq();
if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
+ " operation received seq: " + seq);
// 這裡的finished為false
// token 代表要pause的Activity
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
configChanges,
seq);
}
// 忽略..
}
private class H extends Handler {
public void handleMessage(Message msg) {
// ......
case PAUSE_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
SomeArgs args = (SomeArgs) msg.obj;
handlePauseActivity((IBinder) args.arg1, false,
(args.argi1 & USER_LEAVING) != 0, args.argi2,
(args.argi1 & DONT_REPORT) != 0, args.argi3);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
// ......
}
}
private void handlePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport, int seq) {
// ......
// 擷取ActivityClientRecord
ActivityClientRecord r = mActivities.get(token);
// 調用Activity的onPause
performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
// ......
// 通知AMS已經暫停, 可以繼續AMS還沒完成的事,啟動新的Activity
if (!dontReport) {
try {
ActivityManager.getService().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
// ......
}
通知AMS已經暫停,啟動新的App
暫停目前Activity後,通知AMS已經暫停, 可以繼續AMS還沒完成的事,啟動新的App,主要是調用了Process.start函數,通過LocalSocket和ZygoteServer通信,fork一個新的程序。注意這裡使用的是Socket通信,并不是Binder。因為zygote程序内加載了preload()方法中的所有資源,當需要fork新程序時,采用copy on write技術,是以fork出的新程序可以直接使用預加載的資源,并調用ZygoteInit.nativeZygoteInit()執行Binder驅動程式初始化的相關工作了,才使得程序中的Binder對象能夠順利地進行Binder程序間通信,最後執行新程序中的android.app.ActivityThread類中的Main函數,在main函數調用了attach,接着有調用AMS的attachApplication,用于生命周期的回調。
public final class ActivityThread {
// ......
public static void main(String[] args) {
// ......
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
Looper.loop();
// ......
}
private void attach(boolean system) {
// ......
final IActivityManager mgr = ActivityManager.getService();
try {
// 把mAppThread傳給AMS,用來程序通信,進入AMS的attachApplication函數中
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
// ......
}
}
建立Application
通過Binder驅動程式,執行流程又回到AMS中,調用ActivityManagerService的attachApplication函數中,主要做了2件事 1. 通過Binder驅動程式調用ApplicationThread的bindApplication。 2. 通過Binder驅動調用ApplicationThread的scheduleLaunchActivity。
public class ActivityManagerService ... {
// ......
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
// ......
private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
// ......
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
// ......
}
}
通過Binder驅動程式調用ApplicationThread的bindApplication。然後利用mH.sendMessage最終會執行到ActivityThread中handleBindApplication函數,在這個函數主要是建立了Application,并調用了attach和onCreate方法。
public final class ActivityThread {
// ......
private void handleBindApplication(AppBindData data) {
Application app;
// ......
try {
// ......
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
// 建立Application并調用了attach方法
app = data.info.makeApplication(data.restrictedBackupMode, null);
// 把app賦給全局變量
mInitialApplication = app;
// ......
// 調用了onCreate方法
mInstrumentation.callApplicationOnCreate(app);
}
// ......
}
public final class LoadedApk {
public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {
Application app = null;
String appClass = mApplicationInfo.className;
// forceDefaultAppClass為false,如果沒有沒有指定就會加載預設的
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
// ...... 建立一個Context對象
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// 調用Instrumentation的newApplication
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
// ......
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
}
}
public class Instrumentation {
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
}
建立Activity
通過Binder驅動程式調用ApplicationThread的scheduleLaunchActivity。然後利用mH.sendMessage最終會執行到ActivityThread中handleLaunchActivity函數,在這個函數主要是建立了Activity,并調用了attach和onCreate等生命周期方法。
public final class ActivityThread {
private class ApplicationThread extends IApplicationThread.Stub {
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, Configuration overrideConfig,CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,int procState, Bundle state, PersistableBundle persistentState,List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);
// 發送msg,在H.handleMessage響應
sendMessage(H.LAUNCH_ACTIVITY, r);
}
}
private class H extends Handler {
public void handleMessage(Message msg) {
// ......
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
// ......
}
}
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
// ..... 建立Activity, 并調用onCreate, onStart, onPostCreate以及onRestoreInstanceState(分情況調用),
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
// ...... 調用onResume, onPostResume
handleResumeActivity(r.token, false, r.isForward,!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
// ......
}
}
調用performLaunchActivity,建立Activity, 并調用onCreate, onStart, onPostCreate以及onRestoreInstanceState(分情況調用), 接下來我們繼續看:
public final class ActivityThread {
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// ...... 建立Context
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
// 執行個體化一個Activity對象
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
// ......
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
// ......
}
// ......
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
// ......初始化Activity成員變量
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback);
// ...... 調用Activity的onCreate函數
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
// ...... 調用Activity的onStart函數
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
// ...... 調用Activity的onRestoreInstanceState函數
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
// ...... 調用Activity的onPostCreate函數
if (!r.activity.mFinished) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
// ......
}
r.activity = activity;
// ...... 添加到集合中,token是key
mActivities.put(r.token, r);
}
}
調用handleResumeActivity,調用onResume, onPostResume生命周期方法,然後調用makeVisible, 添加View到WindowManager,WindowManager的實作類是WindowManagerImpl,WindowManagerImpl的addView又調用了WindowManagerGloble.addView, 建立ViewRootImpl對象,并調用了setView函數。(有點扯遠了,有興趣的小夥伴可以去看看),
當線程空閑的時候,調用AMS的activityIdle,最終會調回ApplicationThread.scheduleStopActivity.
最後Activity進入Resumed,并通知AMS
public final class ActivityThread {
public final ActivityClientRecord performResumeActivity(IBinder token,
boolean clearHide, String reason) {
// 根據token取出ActivityClientRecord
ActivityClientRecord r = mActivities.get(token);
// 調用onResume, onPostResume
r = performResumeActivity(token, clearHide, reason);
// .......
// 添加View到WindowManager
if (r.activity.mVisibleFromClient) {
r.activity.makeVisible();
}
if (!r.onlyLocalRequest) {
r.nextIdle = mNewActivities;
mNewActivities = r;
// ...... 當線程空閑時,調用AMS的activityIdle
Looper.myQueue().addIdleHandler(new Idler());
}
r.onlyLocalRequest = false;
通知AMS, Activity已經進入了resumed狀态
if (reallyResume) {
try {
ActivityManager.getService().activityResumed(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}
到這裡一個新的App,就完成啟動了,整個App啟動過程執行了很多步驟,最後畫個圖,幫助大家了解。
參考連結:
https://blog.csdn.net/luoshengyang/article/details/6689748blog.csdn.net
播客位址
木易楊的部落格 | YGS Blogshineygs.github.io