當你點擊桌面App的圖標到底發生了什麼,上篇文章咱們大概簡述了流程java
Launcher
所在的進程,當從某App啓動遠程進程,則發起進程是App所在的進程,發起進程首先須要經過Binder
發送信息給system_server
進程Process.start
方法,經過Socket
向Zygote
進程發送新建進程的請求ZygoteInit.main()
後進入runSelectLoop()
循環體,當有客戶端鏈接時,便會執行ZygoteConnection.runOnce()
方法,再通過層層調用後fork
出新的應用進程handleChildProc
方法,設置進程名,打開binder驅動,啓動新的binder線程,設置art虛擬機參數,反射目標類的main
方法,即調用ActivityThread.main()
方法此次咱們來詳細的分析一下源碼,基於API 27android
當你點擊桌面上的App圖標,Launcher捕獲點擊事件,其過程爲Launcher#onClick
-> Launcher#onClickAppShortcut
->Launcher#startAppShortcutOrInfoActivity
->Launcher#startActivitySafely
-> Activity#startActivity
最終調用了 startActivity(intent, optsBundle);
方法git
下面咱們從startActivity(intent, optsBundle);
方法開始分析調用流程bash
上方咱們說到了Activity.startActivity
,點進源碼發現調用的是Activity#startActivityForResult
,其中還調用到了Instrumentation#execStartActivity
這個方法,源碼以下app
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
startActivityForResult(intent, requestCode, null);
}
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
...
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
...
}
複製代碼
在Instrumentation.execStartActivity
中,咱們發現他調用了ActivityManager#getService()#startActivity
,其中ActivityManager#getService()
返回的是IActivityManager
類型的Binder對象,他的具體實如今ActivityManagerService
async
public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, String target, Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
ActivityManager源碼
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
複製代碼
咱們查看ActivityManagerService.startActivity
源碼,發現他調用了ActivityManagerService#startActivityAsUser
,該方法又調用了ActivityStarter#startActivityMayWait
源碼以下ide
public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
}
複製代碼
咱們查看ActivityStarter.startActivityMayWait
源碼發現他調用了ActivityStarter#startActivityLocked
,接着是ActivityStarter#startActivity
,而後是ActivityStarter#startActivityUnchecked
,其中調用了ActivityStackSupervisor#resumeFocusedStackTopActivityLocked
oop
final int startActivityMayWait(IApplicationThread caller, int callingUid, String callingPackage, Intent intent, String resolvedType, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, WaitResult outResult, Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId, TaskRecord inTask, String reason) {
...
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
reason);
...
}
int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent, String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, TaskRecord inTask, String reason) {
...
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
inTask);
}
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, TaskRecord inTask) {
...
return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
options, inTask, outActivity);
}
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) {
...
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity);
...
}
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) {
...
mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
mOptions);
...
}
複製代碼
咱們查看ActivityStackSupervisor.resumeFocusedStackTopActivityLocked
他調用了ActivityStack#resumeTopActivityUncheckedLocked
,而後是ActivityStack#resumeTopActivityInnerLocked
,接着又回到了ActivityStackSupervisor.java
,調用了ActivityStackSupervisor#startSpecificActivityLocked
,這個方法要判斷啓動的App進程是否存在,存在就直接啓動Activity,若是不存在就把進程建立出來ui
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
...
if (app != null && app.thread != null) {
...
// 若是進程已存在,則通知進程啓動組件
realStartActivityLocked(r, app, andResume, checkConfig);
return;
...
}
// 不然先將進程建立出來
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
...
}
複製代碼
咱們這裏分析進程不存在的狀況,這裏的mService
指的是ActivityManagerService
,咱們查看ActivityManagerService#startProcessLocked
源碼以下this
private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
...
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, entryPointArgs);
...
}
複製代碼
最終調用Process.start
來開啓新進程,這個進程的入口就會在android.app.ActivityThread.java
的main
方法,咱們下面繼續分析ActivityThread#main
ActivityThread#main
方法其中調用了ActivityThread#attach
方法,這個方法中的ActivityManager.getService()
返回的是IActivityManager
類型的Binder
對象,其實現類是ActivityManagerService
,源碼以下
public static void main(String[] args) {
...
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
...
Looper.loop();
...
}
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
...
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
...
}
...
}
...
}
複製代碼
如今咱們又回到了ActivityManagerService
中,查看其attachApplication
方法,發現調用了thread#bindApplication
和mStackSupervisor#attachApplicationLocked
,咱們一次講解這倆個方法做用
public final void attachApplication(IApplicationThread thread) {
...
attachApplicationLocked(thread, callingPid);
...
}
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) {
...
}
}
...
}
複製代碼
上面說到的thread#bindApplication
中的thread
類型是ApplicationThread
,是ActivityThread
的一個內部類,繼承自IApplicationThread.Stub
,咱們查看ApplicationThread#bindApplication
方法,我發現調用了ActivityThread#sendMessage
方法,它內部調用mH.sendMessage
來發送消息,其中mH
是ActivityThread
的一個內部類H
的一個實例
public final void bindApplication(String processName, ApplicationInfo appInfo, List<ProviderInfo> providers, ComponentName instrumentationName, ProfilerInfo profilerInfo, Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection, int debugMode, boolean enableBinderTracking, boolean trackAllocation, boolean isRestrictedBackupMode, boolean persistent, Configuration config, CompatibilityInfo compatInfo, Map services, Bundle coreSettings, String buildSerial) {
...
sendMessage(H.BIND_APPLICATION, data);
}
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
+ ": " + arg1 + " / " + obj);
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
複製代碼
咱們來看一下H這個內部類的handleMessage,最終走到了ActivityThread#handleBindApplication方法
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);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
}
複製代碼
從源碼中咱們發現,他首先建立了mInstrumentation
對象,調用data#info#makeApplication
來建立Application
對象,其中data#info
表明的是LoadedApk
的一個實例,查看LoadedApk#makeApplication
方法能夠看到,內部調用了Instrumentation#newApplication
方法,這個方法內部調用Class#newInstance()
來完成對Application
的實例化,而後調用Application#attach(context)
來綁定Context
上面建立完Application
後,就調用Instrumentation#callApplicationOnCreate
走Application
的onCreate
生命週期,源碼以下
private void handleBindApplication(AppBindData data) {
...
final InstrumentationInfo ii;
...
// 建立 mInstrumentation 實例
if (ii != null) {
final ApplicationInfo instrApp = new ApplicationInfo();
ii.copyTo(instrApp);
instrApp.initForUser(UserHandle.myUserId());
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
try {
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
...
}
...
} else {
mInstrumentation = new Instrumentation();
}
...
Application app;
...
// 建立 Application 實例
try {
...
app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
...
try {
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
}
} finally {
...
}
...
}
// http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/LoadedApk.java#959
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
...
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
...
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if (instrumentation != null) {// 傳入爲 null 因此不走
try {
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
}
}
...
return app;
}
// http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/Instrumentation.java#1084
public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return newApplication(cl.loadClass(className), context);
}
static public Application newApplication(Class<?> clazz, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
複製代碼
上面說完了thread#bindApplication
這個方法,下面咱們繼續說mStackSupervisor#attachApplicationLocked
這個方法,其mStackSupervisor
是ActivityStackSupervisor
的一個實例,咱們查看ActivityStackSupervisor#attachApplicationLocked
方法發現其中調用了ActivityStackSupervisor#realStartActivityLocked
,這個方法調用了app#thread#scheduleLaunchActivity
,源碼以下
// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java#956
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
...
if (realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
...
}
...
}
// http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java#1313
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException {
...
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
r.persistentState, results, newIntents, !andResume,
mService.isNextTransitionForward(), profilerInfo);
...
}
複製代碼
上面說到app#thread#scheduleLaunchActivity
,這個裏面的thread
是IApplicationThread
,他的實現類是ActivityThread#ApplicationThread
,咱們查看ActivityThread#ApplicationThread#scheduleLaunchActivity
方法中的代碼,發現最終是發送了LAUNCH_ACTIVITY
的消息,發送消息咱們再9 ,10步驟中分析過,咱們直接查看處理消息的代碼,在 H#handleMessage
方法中,咱們能夠看到他會接收並處理不少四大組件的相關操做,咱們查看 LAUNCH_ACTIVITY
的處理,發現其處理方法是調用了ActivityThread#handleLaunchActivity
,這個方法再次涉及到了Instrumentation類
,以前建立Application
的時候用到了他,現在建立Activity
也用到了他,其中Instrumentation#newActivity
是經過 Class.newInstance()
來實例化Activity
,實例化完成後回到ActivityThread#performLaunchActivity
中,讓Activity
依附到window中,而後callActivityOnCreate走Activity
的onCreate
的生命週期,涉及到的源碼以下
// http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityThread.java#756
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) {
...
sendMessage(H.LAUNCH_ACTIVITY, r);
}
// http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityThread.java#1580
public void handleMessage(Message msg) {
...
switch (msg.what) {
...
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;
...
}
}
// http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityThread.java#2833
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
...
Activity a = performLaunchActivity(r, customIntent);
...
}
// http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/app/ActivityThread.java#2644
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
} catch (Exception e) {
...
}
try {
// 返回以前建立過的 application 對象
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
...
if (activity != null) {
...
// attach 到 window 上
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);
...
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
}
} catch (Exception e) {
...
}
return activity;
}
public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
複製代碼
概述一下大體流程
Launcher
進程,經過ActivityManagerService
Binder IPC的形式向system_server
進程發起startActivity
的請求system_server
進程接收到請求後,經過Process.start
方法向zygote
進程發送建立進程的請求zygote
進程fork
出新的子進程,即App
進程ActivityThread.main
方法中,這時運行在App
進程中,經過ActivityManagerService
Binder IPC的形式向system_server
進程發起attachApplication
請求system_server
接收到請求後,進行一些列準備工做後,再經過Binder IPC向App
進程發送scheduleLaunchActivity
請求App
進程binder線程(ApplicationThread)
收到請求後,經過Handler
向主線程發送LAUNCH_ACTIVITY
消息Activity
,並回調Activity
的onCreate