相關文章
Android系統架構與系統源碼目錄
Android系統啓動流程(一)解析init進程啓動過程
Android系統啓動流程(二)解析Zygote進程啓動過程
Android系統啓動流程(三)解析SyetemServer進程啓動過程
Android系統啓動流程(四)Launcher啓動過程與系統啓動流程
Android應用程序進程啓動過程(前篇)
Android應用程序進程啓動過程(後篇)javascript
在此前的文章中,我講過了Android系統啓動流程和Android應用進程啓動過程,這一篇瓜熟蒂落來學習Android 7.0的應用程序的啓動過程。分析應用程序的啓動過程其實就是分析根Activity的啓動過程。html
在 Android系統啓動流程(四)Launcher啓動過程與系統啓動流程這篇文章我講過Launcher啓動後會將已安裝應用程序的快捷圖標顯示到界面上,當咱們點擊應用程序的快捷圖標時就會調用Launcher的startActivitySafely方法,以下所示。
packages/apps/Launcher3/src/com/android/launcher3/Launcher.javajava
public boolean startActivitySafely(View v, Intent intent, Object tag) {
...
try {
success = startActivity(v, intent, tag);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
}
return success;
}複製代碼
startActivitySafely函數中主要就是調用了startActivity函數:
packages/apps/Launcher3/src/com/android/launcher3/Launcher.javaandroid
private boolean startActivity(View v, Intent intent, Object tag) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//1
try {
...
if (user == null || user.equals(UserHandleCompat.myUserHandle())) {
StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
try {
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
.penaltyLog().build());
startActivity(intent, optsBundle);//2
} finally {
StrictMode.setVmPolicy(oldPolicy);
}
} else {
launcherApps.startActivityForProfile(intent.getComponent(), user,
intent.getSourceBounds(), optsBundle);
}
return true;
} catch (SecurityException e) {
...
}
return false;
}複製代碼
在註釋1處設置Flag爲Intent.FLAG_ACTIVITY_NEW_TASK,這樣根Activity會在新的任務棧中啓動。在註釋2處調用了startActivity函數:
frameworks/base/core/java/android/app/Activity.java微信
Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}複製代碼
startActivity會調用startActivityForResult函數,其中第二個參數爲-1,表示Launcher不須要知道Activity啓動的結果,startActivityForResult函數的代碼以下所示。
frameworks/base/core/java/android/app/Activity.java架構
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
...
} else {
...
}
}複製代碼
mParent是Activity類型的,表示當前Activity的父類。由於目前根Activity尚未建立出來,所以,mParent == null成立。接着調用Instrumentation的execStartActivity方法,Instrumentation主要用來監控應用程序和系統的交互,execStartActivity方法的代碼以下所示。
frameworks/base/core/java/android/app/Instrumentation.javaapp
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityManagerNative.getDefault()
.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;
}複製代碼
首先會調用ActivityManagerNative的getDefault來獲取ActivityManageService(之後簡稱爲AMS)的代理對象,接着調用它的startActivity方法。首先咱們先來查看ActivityManagerNative的getDefault方法作了什麼:
frameworks/base/core/java/android/app/ActivityManagerNative.javaasync
static public IActivityManager getDefault() {
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");//1
if (false) {
Log.v("ActivityManager", "default service binder = " + b);
}
IActivityManager am = asInterface(b);//2
if (false) {
Log.v("ActivityManager", "default service = " + am);
}
return am;
}
};
}複製代碼
getDefault方法調用了gDefault的get方法,咱們接着往下看,gDefault 是一個Singleton類。註釋1處獲得名爲"activity"的Service代理對象,也就是ActivityManagerService的代理對象。接着在註釋2處將它封裝成ActivityManagerProxy(之後簡稱爲AMP)類型對象,並將它保存到gDefault中,此後調用ActivityManagerNative的getDefault方法就會直接得到AMS的代理AMP對象。
回到Instrumentation類的execStartActivity方法中,從上面得知就是調用AMP的startActivity,其中AMP是ActivityManagerNative的內部類,代碼以下所示。
frameworks/base/core/java/android/app/ActivityManagerNative.javaide
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
data.writeString(callingPackage);
intent.writeToParcel(data, 0);
data.writeString(resolvedType);
data.writeStrongBinder(resultTo);
data.writeString(resultWho);
data.writeInt(requestCode);
data.writeInt(startFlags);
if (profilerInfo != null) {
data.writeInt(1);
profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
data.writeInt(0);
}
if (options != null) {
data.writeInt(1);
options.writeToParcel(data, 0);
} else {
data.writeInt(0);
}
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);//1
reply.readException();
int result = reply.readInt();
reply.recycle();
data.recycle();
return result;
}複製代碼
首先會將傳入的參數寫入到Parcel類型的data中。在註釋1處經過IBinder對象mRemote想AMS發送一個START_ACTIVITY_TRANSACTION類型的進程間通訊請求。那麼服務端AMS就會從Binder線程池中讀取咱們客戶端發來的數據,最終會調用ActivityManagerNative的onTransact方法中執行,以下所示。
frameworks/base/core/java/android/app/ActivityManagerNative.java函數
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case START_ACTIVITY_TRANSACTION:
{
...
int result = startActivity(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
reply.writeNoException();
reply.writeInt(result);
return true;
}
}複製代碼
onTransact中會調用AMS的startActivity方法,以下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
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());
}複製代碼
爲了便於理解,給出Launcher到AMS調用過程的時序圖。
AMS的startActivity方法中return了startActivityAsUser方法:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
@Override
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);
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null);複製代碼
startActivityAsUser方法中又return了mActivityStarter的startActivityMayWait方法,代碼以下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
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, IActivityManager.WaitResult outResult, Configuration config,
Bundle bOptions, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask) {
...
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, container,
inTask);
...
return res;
}
}複製代碼
又調用了startActivityLocked方法,代碼以下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
final 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, ActivityStackSupervisor.ActivityContainer container,
TaskRecord inTask) {
...
doPendingActivityLaunchesLocked(false);
...
return err;
}複製代碼
startActivityLocked函數代碼很是多,咱們只須要關注doPendingActivityLaunchesLocked方法,代碼以下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
final void doPendingActivityLaunchesLocked(boolean doResume) {
while (!mPendingActivityLaunches.isEmpty()) {
final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
try {
final int result = startActivityUnchecked(
pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null, null);
postStartActivityUncheckedProcessing(
pal.r, result, mSupervisor.mFocusedStack.mStackId, mSourceRecord,
mTargetStack);
} catch (Exception e) {
Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
pal.sendErrorResult(e.getMessage());
}
}
}複製代碼
接着又調用startActivityUnchecked方法:
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
...
mSupervisor.resumeFocusedStackTopActivityLocked();
...
return START_SUCCESS;
}複製代碼
startActivityUnchecked方法中調用了ActivityStackSupervisor類型的mSupervisor的resumeFocusedStackTopActivityLocked方法,以下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
boolean resumeFocusedStackTopActivityLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (targetStack != null && isFocusedStack(targetStack)) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
if (r == null || r.state != RESUMED) {
mFocusedStack.resumeTopActivityUncheckedLocked(null, null);//1
}
return false;
}複製代碼
在註釋1處又調用了ActivityStack類型mFocusedStack的resumeTopActivityUncheckedLocked方法:
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
...
try {
...
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}複製代碼
緊接着查看ActivityStack的resumeTopActivityInnerLocked方法:
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;複製代碼
resumeTopActivityInnerLocked方法代碼很是多,咱們只須要關注調用了ActivityStackSupervisor類型mStackSupervisor的startSpecificActivityLocked方法,代碼以下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
if (app != null && app.thread != null) {//1
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);//2
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}複製代碼
在註釋1處若是當前Activity所在的Application運行的話,會執行註釋2處的代碼。realStartActivityLocked方法的代碼以下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
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, new Configuration(mService.mConfiguration),
new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
...
return true;
}複製代碼
這裏的 app.thread指的是IApplicationThread,它的實現是ActivityThread的內部類ApplicationThread,其中ApplicationThread繼承了ApplicationThreadNative,而ApplicationThreadNative繼承了Binder並實現了IApplicationThread接口。
講到這裏再給出ActivityManageService到ApplicationThread調用過程的時序圖,以下圖所示。
Android應用程序進程啓動過程(前篇)這篇文章中提到過ActivityThread,在應用程序進程啓動時會建立ActivityThread實例。ActivityThread做爲應用程序進程的核心類,它是如何啓動應用程序(Activity)的呢?咱們接着往下看。
根據上文接着查看ApplicationThread的scheduleLaunchActivity方法,代碼以下所示。
frameworks/base/core/java/android/app/ActivityThread.java
@Override
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);
sendMessage(H.LAUNCH_ACTIVITY, r);
}複製代碼
scheduleLaunchActivity方法會將啓動Activity的參數封裝成ActivityClientRecord ,再將ActivityClientRecord經過sendMessage方法嚮應用進程的主線程發送類型爲LAUNCH_ACTIVITY的消息,sendMessage方法的代碼以下所示。
frameworks/base/core/java/android/app/ActivityThread.java
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
...
mH.sendMessage(msg);
}複製代碼
這裏mH指的是H,它是ActivityThread的內部類並繼承Handler,H的代碼以下所示。
frameworks/base/core/java/android/app/ActivityThread.java
private class H extends Handler {
public static final int LAUNCH_ACTIVITY = 100;
public static final int PAUSE_ACTIVITY = 101;
...
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;//1
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);//2
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");//3
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
case RELAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
handleRelaunchActivity(r);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
...
}複製代碼
查看H的handleMessage方法中對LAUNCH_ACTIVITY的處理,在註釋1處將傳過來的msg的成員變量obj轉換爲ActivityClientRecord。
在註釋2處經過getPackageInfoNoCheck方法得到LoadedApk類型的對象並賦值給ActivityClientRecord 的成員變量packageInfo 。應用程序進程要啓動Activity時須要將該Activity所屬的APK加載進來,而LoadedApk就是用來描述已加載的APK文件。
在註釋3處調用handleLaunchActivity方法,代碼以下所示。
frameworks/base/core/java/android/app/ActivityThread.java
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
...
Activity a = performLaunchActivity(r, customIntent);//1
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);//1
if (!r.activity.mFinished && r.startsNotResumed) {
performPauseActivityIfNeeded(r, reason);
if (r.isPreHoneycomb()) {
r.state = oldState;
}
}
} else {
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
}複製代碼
註釋1處的performLaunchActivity方法用來啓動Activity ,註釋2處的代碼用來將Activity 的狀態置爲Resume。若是該Activity爲null則會通知ActivityManager中止啓動Activity。來查看performLaunchActivity方法作了什麼:
frameworks/base/core/java/android/app/ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
ActivityInfo aInfo = r.activityInfo;//1
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);//2
}
ComponentName component = r.intent.getComponent();//3
...
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);//4
...
}
} catch (Exception e) {
...
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);//5
...
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);//6
...
}
/** *7 */
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);
...
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);//8
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
}
return activity;
}複製代碼
註釋1處用來獲取ActivityInfo,在註釋2處獲取APK文件的描述類LoadedApk。註釋3處獲取要啓動的Activity的ComponentName類,ComponentName類中保存了該Activity的包名和類名。註釋4處根據ComponentName中存儲的Activity類名,用類加載器來建立該Activity的實例。註釋5處用來建立Application,makeApplication方法內部會調用Application的onCreate方法。註釋6處用來建立要啓動Activity的上下文環境。註釋7處調用Activity的attach方法初始化Activity,attach方法中會建立Window對象(PhoneWindow)並與Activity自身進行關聯。註釋8處會調用Instrumentation的callActivityOnCreate方法來啓動Activity:
frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);//1
postPerformCreate(activity);
}複製代碼
註釋1處調用了Activity的performCreate方法,代碼以下所示。
frameworks/base/core/java/android/app/Activity.java
final void performCreate(Bundle icicle) {
restoreHasCurrentPermissionRequest(icicle);
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}複製代碼
performCreate方法中會調用Activity的onCreate方法,這樣Activity就啓動了,即應用程序就啓動了。
應用程序啓動過程就講到這裏,最後附上ActivityThread啓動Activity的時序圖。
歡迎關注個人微信公衆號,第一時間得到博客更新提醒,以及更多成體系的Android相關原創技術乾貨。
掃一掃下方二維碼或者長按識別二維碼,便可關注。