Android 四大元件之——Acitivity(三) 深入瞭解Activity的啟動流程
阿新 • • 發佈:2018-11-14
上圖為整個Activity的啟動流程
接下來我們大概分析
在我們的Android系統中,應用程式是由Launcher這個應用啟動起來的。當我們安裝好應用程式之後,就會在Launcher的介面上生成一個圖示,我們點選圖示時Launch就會啟動我們的應用程式。
1.點選圖示,launcher呼叫onClick方法
/** * * * @param v The view representing the clicked shortcut. 1.此處的view是指被點選的桌面圖示 */ public void onClick(View v) { // Make sure that rogue clicks don't get through while allapps is // launching, or after the // view has detached (it's possible for this to happen if the view is // removed mid touch). if (v.getWindowToken() == null) { return; } if (!mWorkspace.isFinishedSwitchingState()) { return; } Object tag = v.getTag(); if (tag instanceof ShortcutInfo) { // 開啟快捷方式對應的intent final Intent intent = ((ShortcutInfo) tag).intent; int[] pos = new int[2]; v.getLocationOnScreen(pos); intent.setSourceBounds(new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight())); boolean success = startActivitySafely(v, intent, tag);//2.同時呼叫startActivitySafely
if (success && v instanceof BubbleTextView) { mWaitingForResume = (BubbleTextView) v; mWaitingForResume.setStayPressed(true); } } else if (tag instanceof FolderInfo) { if (v instanceof FolderIcon) { // 開啟資料夾 FolderIcon fi = (FolderIcon) v; handleFolderClick(fi); } } else if (v == mAllAppsButton) { // 顯示或者不顯示“全部程式”介面 if (isAllAppsVisible()) { showWorkspace(true); } else { onClickAllAppsButton(v); } } }
boolean startActivitySafely(View v, Intent intent, Object tag) { boolean success = false; try { success = startActivity(v, intent, tag); 由此可見StartActivitySafely(),最終是呼叫startActivity()方法 } 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; }
boolean startActivity(View v, Intent intent, Object tag) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
// Only launch using the new animation if the shortcut has not opted
// out (this is a
// private contract between launcher and may be ignored in the
// future).
boolean useLaunchAnimation = (v != null)
&& !intent.hasExtra(INTENT_EXTRA_IGNORE_LAUNCH_ANIMATION);
if (useLaunchAnimation) {
ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v,
0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
startActivity(intent, opts.toBundle());
} else {
startActivity(intent);
}
return true;
} catch (SecurityException e) {
Toast.makeText(this, R.string.activity_not_found,
Toast.LENGTH_SHORT).show();
Log.e(TAG,
"Launcher does not have the permission to launch "
+ intent
+ ". Make sure to create a MAIN intent-filter for the corresponding activity "
+ "or use the exported attribute for this activity. "
+ "tag=" + tag + " intent=" + intent, e);
}
return false;
}
3.在startActivity()方法中,intent 添加了flag FLAG_ACTIVITY_NEW_TASK , 此標誌為建立新的任務棧,在建立目標
任務棧之前,首先會呼叫ActivityThread類啟動launcher的程序,然後啟動目標應用的任務棧,啟動完成之後,目標應用的任務棧會通知
ActivityThread呼叫launcher的onPause方法。此時,ActivityThread啟動新的應用程序(也就是目標應用的程序)。
4.目標應用的程序通過loadClass載入MainActivity,然後通過H(handler)來控制MainActivity的生命週期