【Android 启动过程】Activity 启动源码分析 ( Activity -> AMS、主线程阶段 )
文章目錄
- 一、Activity 啟動(dòng)源碼分析 ( Activity -> AMS 階段 )
一、Activity 啟動(dòng)源碼分析 ( Activity -> AMS 階段 )
調(diào)用 startActivity(new Intent()); 方法啟動(dòng) Activity , 調(diào)用方法原型如下 :
public class Activity extends ContextThemeWrapperimplements LayoutInflater.Factory2,Window.Callback, KeyEvent.Callback,OnCreateContextMenuListener, ComponentCallbacks2,Window.OnWindowDismissedCallback,AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {/*** 與 {@link #startActivity(Intent, Bundle)} 方法相同 , * Bundle options 參數(shù)設(shè)置為 null** @param intent 啟動(dòng)的意圖.** @throws android.content.ActivityNotFoundException** @see #startActivity(Intent, Bundle)* @see #startActivityForResult*/@Overridepublic void startActivity(Intent intent) {this.startActivity(intent, null);} }完整代碼查看 frameworks/base/core/java/android/app/Activity.java 地址 ;
在 public void startActivity(Intent intent) 方法中 , 執(zhí)行 this.startActivity(intent, null) 方法 , 方法原型如下 :
public class Activity extends ContextThemeWrapperimplements LayoutInflater.Factory2,Window.Callback, KeyEvent.Callback,OnCreateContextMenuListener, ComponentCallbacks2,Window.OnWindowDismissedCallback,AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {/*** 開展一項(xiàng)新活動(dòng)。您將不會(huì)收到關(guān)于何時(shí)開始的任何信息* 活動(dòng)退出。此實(shí)現(xiàn)將覆蓋基本版本,* 提供關(guān)于* 執(zhí)行啟動(dòng)的活動(dòng)。因?yàn)檫@個(gè)額外的* 信息,{@link Intent#FLAG_ACTIVITY_NEW_TASK}啟動(dòng)標(biāo)志不可用* 必修的;如果未指定,則新活動(dòng)將添加到* 調(diào)用方的任務(wù)。** <p>此方法引發(fā){@link android.content.ActivityNotFoundException}* 如果沒有找到運(yùn)行給定意圖的活動(dòng)。** @param intent 要啟動(dòng)的意圖.* @param options 有關(guān)如何啟動(dòng)活動(dòng)的其他選項(xiàng).* 更多細(xì)節(jié)查看 {@link android.content.Context#startActivity(Intent, Bundle)}* Context.startActivity(Intent, Bundle)} .** @throws android.content.ActivityNotFoundException** @see #startActivity(Intent)* @see #startActivityForResult*/@Overridepublic void startActivity(Intent intent, @Nullable Bundle options) {if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)&& mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY)) {if (TextUtils.equals(getPackageName(),intent.resolveActivity(getPackageManager()).getPackageName())) {// Apply Autofill restore mechanism on the started activity by startActivity()final IBinder token =mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);// Remove restore ability from current activitymIntent.removeExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN);mIntent.removeExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY);// Put restore tokenintent.putExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN, token);intent.putExtra(AutofillManager.EXTRA_RESTORE_CROSS_ACTIVITY, true);}}// 如果有選項(xiàng) , 執(zhí)行 startActivityForResult 3 參數(shù)方法if (options != null) {startActivityForResult(intent, -1, options);} else {// 如果沒有選項(xiàng) , 執(zhí)行 startActivityForResult 2 參數(shù)方法// Note we want to go through this call for compatibility with// applications that may have overridden the method.startActivityForResult(intent, -1);}} }完整代碼查看 frameworks/base/core/java/android/app/Activity.java 地址 ;
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) 函數(shù)原型 :
public class Activity extends ContextThemeWrapperimplements LayoutInflater.Factory2,Window.Callback, KeyEvent.Callback,OnCreateContextMenuListener, ComponentCallbacks2,Window.OnWindowDismissedCallback,AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {/*** 啟動(dòng)一項(xiàng)活動(dòng),在該活動(dòng)完成時(shí)希望獲得結(jié)果。* 當(dāng)此活動(dòng)退出時(shí),您的* 將使用給定的請(qǐng)求代碼調(diào)用onActivityResult()方法。* 使用否定的requestCode與調(diào)用* {@link#startActivity}(該活動(dòng)不是作為子活動(dòng)啟動(dòng)的)。** <p>請(qǐng)注意,此方法僅應(yīng)與Intent協(xié)議一起使用* 定義為返回結(jié)果的。在其他協(xié)議中(例如* {@link Intent#ACTION_MAIN}或{@link Intent#ACTION_VIEW}),您可以* 在你期望的時(shí)候沒有得到結(jié)果。例如,如果您選擇的活動(dòng)* 如果啟動(dòng)使用{@link Intent#FLAG_ACTIVITY_NEW_TASK},則不會(huì)* 運(yùn)行您的任務(wù),您將立即收到取消結(jié)果。** <p>作為特例,如果使用requestCode調(diào)用startActivityForResult()* >=0,在初始的onCreate(Bundle savedInstanceState)/onResume()過程中* 活動(dòng),則在顯示結(jié)果之前不會(huì)顯示窗口* 從已啟動(dòng)的活動(dòng)返回。這是為了避免可見* 重定向到其他活動(dòng)時(shí)閃爍。** <p>此方法引發(fā){@link android.content.ActivityNotFoundException}* 如果沒有找到運(yùn)行給定意圖的活動(dòng)。** @param intent 要啟動(dòng)的意圖.* @param requestCode 如果>=0,則當(dāng)活動(dòng)退出時(shí),此代碼將在onActivityResult()中返回.* @param options 有關(guān)如何啟動(dòng)活動(dòng)的其他選項(xiàng)。* See {@link android.content.Context#startActivity(Intent, Bundle)}* Context.startActivity(Intent, Bundle)} for more details.** @throws android.content.ActivityNotFoundException** @see #startActivity*/public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {if (mParent == null) {options = transferSpringboardActivityOptions(options);// 調(diào)用 Instrumentation 方法 // Instrumentation 負(fù)責(zé)啟動(dòng) Application 和 Activity // 插件化時(shí) , 此處是一個(gè) Hook 點(diǎn)Instrumentation.ActivityResult ar =mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);if (ar != null) {mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(),ar.getResultData());}if (requestCode >= 0) {// 如果此開始要求結(jié)果,我們可以避免// 在收到結(jié)果之前,活動(dòng)是可見的。背景// 此代碼在onCreate(Bundle savedInstanceState)或onResume()期間將保持// 在此期間隱藏活動(dòng),以避免閃爍。// 這只能在請(qǐng)求結(jié)果時(shí)執(zhí)行,因?yàn)?/span>// 這保證了我們會(huì)在// 不管發(fā)生什么,活動(dòng)都已完成。mStartedActivity = true;}cancelInputsAndStartExitTransition(options);// TODO Consider clearing/flushing other event sources and events for child windows.} else {if (options != null) {mParent.startActivityFromChild(this, intent, requestCode, options);} else {// Note we want to go through this method for compatibility with// existing applications that may have overridden it.mParent.startActivityFromChild(this, intent, requestCode);}}} }完整代碼查看 frameworks/base/core/java/android/app/Activity.java ;
分析 mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options) 方法 , 注意傳入的參數(shù)是 777 個(gè)參數(shù) , 函數(shù)原型為 :
public class Instrumentation {/*** 執(zhí)行應(yīng)用程序發(fā)出的startActivity調(diào)用。默認(rèn)值* 實(shí)現(xiàn)負(fù)責(zé)更新任何活動(dòng)的{@link ActivityMonitor}* 對(duì)象并將此調(diào)用分派給系統(tǒng)活動(dòng)管理器;你可以* 覆蓋此選項(xiàng)以監(jiān)視應(yīng)用程序啟動(dòng)活動(dòng),以及* 修改它執(zhí)行時(shí)發(fā)生的情況。* * <p>此方法返回一個(gè){@link ActivityResult}對(duì)象,您可以* 在攔截應(yīng)用程序調(diào)用時(shí)使用,以避免執(zhí)行啟動(dòng)* 活動(dòng)操作,但仍返回應(yīng)用程序運(yùn)行的結(jié)果* 期望。為此,重寫此方法以捕獲對(duì)start的調(diào)用* 活動(dòng),以便返回包含結(jié)果的新ActivityResult* 您希望應(yīng)用程序能夠看到,并且不要調(diào)用超級(jí)用戶* 班級(jí)。請(qǐng)注意,應(yīng)用程序僅在以下情況下才期望結(jié)果:* <var>requestCode</var>is&gt;=0* * <p>此方法引發(fā){@link android.content.ActivityNotFoundException}* 如果沒有找到運(yùn)行給定意圖的活動(dòng)。* * @param who 從中啟動(dòng)活動(dòng)的上下文的參數(shù)。* @param contextThread 活動(dòng)所在上下文的主線程正在啟動(dòng)。* @param token 標(biāo)識(shí)要啟動(dòng)的系統(tǒng)的內(nèi)部令牌活動(dòng);可能為空。* @param target 哪個(gè)活動(dòng)正在執(zhí)行啟動(dòng)(并因此接收任何結(jié)果);如果未進(jìn)行此調(diào)用,則可能為null從一項(xiàng)活動(dòng)中。* @param intent 啟動(dòng)的實(shí)際意圖。* @param requestCode 標(biāo)識(shí)符;如果調(diào)用方不希望得到結(jié)果設(shè)置小于 0。* @param options 參數(shù)選項(xiàng)添加選項(xiàng)。* @return 要強(qiáng)制返回特定結(jié)果,請(qǐng)返回包含所需數(shù)據(jù)的ActivityResult對(duì)象;* 否則返回null。默認(rèn)實(shí)現(xiàn)總是返回null。** @throws android.content.ActivityNotFoundException** @see Activity#startActivity(Intent)* @see Activity#startActivityForResult(Intent, int)* @see Activity#startActivityFromChild** {@hide}*/public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {IApplicationThread whoThread = (IApplicationThread) contextThread;Uri referrer = target != null ? target.onProvideReferrer() : null;if (referrer != null) {intent.putExtra(Intent.EXTRA_REFERRER, referrer);}if (mActivityMonitors != null) {synchronized (mSync) {final int N = mActivityMonitors.size();for (int i=0; i<N; i++) {final ActivityMonitor am = mActivityMonitors.get(i);ActivityResult result = null;if (am.ignoreMatchingSpecificIntents()) {result = am.onStartActivity(intent);}if (result != null) {am.mHits++;return result;} else if (am.match(who, null, intent)) {am.mHits++;if (am.isBlocking()) {return requestCode >= 0 ? am.getResult() : null;}break;}}}}try {intent.migrateExtraStreamToClipData();intent.prepareToLeaveProcess(who);// 在此處調(diào)用 AMS , Binder 機(jī)制獲取 AMSint 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;} }完整代碼查看 frameworks/base/core/java/android/app/Instrumentation.java ;
總結(jié)
以上是生活随笔為你收集整理的【Android 启动过程】Activity 启动源码分析 ( Activity -> AMS、主线程阶段 )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 启动过程】Androi
- 下一篇: 【Android 返回堆栈管理】打印 A