您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“Android App啟動Activity的方法是什么”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Android App啟動Activity的方法是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
讓我們把目光聚焦到ActivityThread
的main方法上。
ActivityThread
的源碼路徑為 /frameworks/base/core/java/android/app/ActivityThread
。
public static void main(String[] args) { ... //請注意這句話,主線程Looper在此處做了prepare的操作 Looper.prepareMainLooper(); // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line. // It will be in the format "seq=114" long startSeq = 0; if (args != null) { for (int i = args.length - 1; i >= 0; --i) { if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) { startSeq = Long.parseLong( args[i].substring(PROC_START_SEQ_IDENT.length())); } } } ActivityThread thread = new ActivityThread(); thread.attach(false, startSeq); if (sMainThreadHandler == null) { //獲取主線程的handler,其實就是ActivityThread里的mH變量 sMainThreadHandler = thread.getHandler(); } //開始循環獲取主線程Message消息 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
繼續從ActivityThread
的attach方法往下追蹤。
private void attach(boolean system, long startSeq) { sCurrentActivityThread = this; mSystemThread = system; if (!system) { //執行此分支 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId()); RuntimeInit.setApplicationObject(mAppThread.asBinder()); final IActivityManager mgr = ActivityManager.getService(); try { mgr.attachApplication(mAppThread, startSeq); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } // Watch for getting close to heap limit. BinderInternal.addGcWatcher(new Runnable() { @Override public void run() { if (!mSomeActivitiesChanged) { return; } Runtime runtime = Runtime.getRuntime(); long dalvikMax = runtime.maxMemory(); long dalvikUsed = runtime.totalMemory() - runtime.freeMemory(); if (dalvikUsed > ((3*dalvikMax)/4)) { if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024) + " total=" + (runtime.totalMemory()/1024) + " used=" + (dalvikUsed/1024)); mSomeActivitiesChanged = false; try { ActivityTaskManager.getService().releaseSomeActivities(mAppThread); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } } }); } else { ... } ViewRootImpl.ConfigChangedCallback configChangedCallback = (Configuration globalConfig) -> { synchronized (mResourcesManager) { // We need to apply this change to the resources immediately, because upon returning // the view hierarchy will be informed about it. if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig, null /* compat */)) { updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(), mResourcesManager.getConfiguration().getLocales()); // This actually changed the resources! Tell everyone about it. if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(globalConfig)) { mPendingConfiguration = globalConfig; sendMessage(H.CONFIGURATION_CHANGED, globalConfig); } } } }; ViewRootImpl.addConfigCallback(configChangedCallback); }
上述代碼調用了IActivityManager
的attachApplication
方法,并傳入了當前的ActivityThread
對象以及啟動序列號。我們將目光轉向ActivityManagerService
。
@Override public final void attachApplication(IApplicationThread thread, long startSeq) { if (thread == null) { throw new SecurityException("Invalid application interface"); } synchronized (this) { int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid, callingUid, startSeq); Binder.restoreCallingIdentity(origId); } }
private boolean attachApplicationLocked(@NonNull IApplicationThread thread, int pid, int callingUid, long startSeq) { ... mAtmInternal.preBindApplication(app.getWindowProcessController()); final ActiveInstrumentation instr2 = app.getActiveInstrumentation(); if (app.isolatedEntryPoint != null) { // This is an isolated process which should just call an entry point instead of // being bound to an application. thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs); } else if (instr2 != null) { thread.bindApplication(processName, appInfo, providers, instr2.mClass, profilerInfo, instr2.mArguments, instr2.mWatcher, instr2.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.isPersistent(), new Configuration(app.getWindowProcessController().getConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, autofillOptions, contentCaptureOptions); } else { thread.bindApplication(processName, appInfo, providers, null, profilerInfo, null, null, null, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.isPersistent(), new Configuration(app.getWindowProcessController().getConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, autofillOptions, contentCaptureOptions); } if (profilerInfo != null) { profilerInfo.closeFd(); profilerInfo = null; } // Make app active after binding application or client may be running requests (e.g // starting activities) before it is ready. app.makeActive(thread, mProcessStats); checkTime(startTime, "attachApplicationLocked: immediately after bindApplication"); mProcessList.updateLruProcessLocked(app, false, null); checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked"); app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); } catch (Exception e) { // todo: Yikes! What should we do? For now we will try to // start another process, but that could easily get us in // an infinite loop of restarting processes... Slog.wtf(TAG, "Exception thrown during bind of " + app, e); app.resetPackageList(mProcessStats); app.unlinkDeathRecipient(); mProcessList.startProcessLocked(app, new HostingRecord("bind-fail", processName)); return false; } // Remove this record from the list of starting applications. mPersistentStartingProcesses.remove(app); if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES, "Attach application locked removing on hold: " + app); mProcessesOnHold.remove(app); boolean badApp = false; boolean didSomething = false; // See if the top visible activity is waiting to run in this process... if (normalMode) { try { didSomething = mAtmInternal.attachApplication(app.getWindowProcessController()); } catch (Exception e) { Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); badApp = true; } } // Find any services that should be running in this process... if (!badApp) { try { didSomething |= mServices.attachApplicationLocked(app, processName); checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked"); } catch (Exception e) { Slog.wtf(TAG, "Exception thrown starting services in " + app, e); badApp = true; } } ... return true; }
上面這段內容有兩段關鍵的語句,一是調用了 IApplicationThread
的bindApplication
方法;二是調用了ActivityTaskManagerInternal
的attachApplication
方法。我們先來看位于ActivityThread
中的bindApplication
這個調用。
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, AutofillOptions autofillOptions, ContentCaptureOptions contentCaptureOptions) { ... sendMessage(H.BIND_APPLICATION, data); }
方法的結尾,發送了一條what值為H.BIND_APPLICATION
的消息。
我們去Handler中找到這條消息的代碼段。
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;
private void handleBindApplication(AppBindData data) { // Register the UI Thread as a sensitive thread to the runtime. ... Application app; try { //在這里創建了Application對象 app = data.info.makeApplication(data.restrictedBackupMode, null); // Propagate autofill compat state app.setAutofillOptions(data.autofillOptions); // Propagate Content Capture options app.setContentCaptureOptions(data.contentCaptureOptions); mInitialApplication = app; // don't bring up providers in restricted mode; they may depend on the // app's custom Application class if (!data.restrictedBackupMode) { if (!ArrayUtils.isEmpty(data.providers)) { installContentProviders(app, data.providers); } } // Do this after providers, since instrumentation tests generally start their // test thread at this point, and we don't want that racing. try { mInstrumentation.onCreate(data.instrumentationArgs); } catch (Exception e) { throw new RuntimeException( "Exception thrown in onCreate() of " + data.instrumentationName + ": " + e.toString(), e); } try { //在這里調用了Application onCreate方法 mInstrumentation.callApplicationOnCreate(app); } catch (Exception e) { if (!mInstrumentation.onException(app, e)) { throw new RuntimeException( "Unable to create application " + app.getClass().getName() + ": " + e.toString(), e); } } } finally { // If the app targets < O-MR1, or doesn't change the thread policy // during startup, clobber the policy to maintain behavior of b/36951662 if (data.appInfo.targetSdkVersion < Build.VERSION_CODES.O_MR1 || StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) { StrictMode.setThreadPolicy(savedPolicy); } } // 加載字體資源 FontsContract.setApplicationContextForResources(appContext); if (!Process.isIsolated()) { try { final ApplicationInfo info = getPackageManager().getApplicationInfo( data.appInfo.packageName, PackageManager.GET_META_DATA /*flags*/, UserHandle.myUserId()); if (info.metaData != null) { final int preloadedFontsResource = info.metaData.getInt( ApplicationInfo.METADATA_PRELOADED_FONTS, 0); if (preloadedFontsResource != 0) { data.info.getResources().preloadFonts(preloadedFontsResource); } } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } }
app = data.info.makeApplication(data.restrictedBackupMode, null);
這段代碼是一段關鍵代碼,它創建了Application以及全局的Application Context對象, 我們深入往下看一下:
源碼位置為 frameworks/base/core/java/android/app/LoadedApk.java
。
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { if (mApplication != null) { return mApplication; } Application app = null; //如果manifest application標簽的name屬性指定了application類,則使用指定的類,否則默認使用android.app.Application String appClass = mApplicationInfo.className; if (forceDefaultAppClass || (appClass == null)) { appClass = "android.app.Application"; } try { java.lang.ClassLoader cl = getClassLoader(); if (!mPackageName.equals("android")) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "initializeJavaContextClassLoader"); initializeJavaContextClassLoader(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } //創建全局的Application Context ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); //創建Application對象 app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); } catch (Exception e) { if (!mActivityThread.mInstrumentation.onException(app, e)) { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); throw new RuntimeException( "Unable to instantiate application " + appClass + ": " + e.toString(), e); } } mActivityThread.mAllApplications.add(app); mApplication = app; if (instrumentation != null) { try { instrumentation.callApplicationOnCreate(app); } catch (Exception e) { if (!instrumentation.onException(app, e)) { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); throw new RuntimeException( "Unable to create application " + app.getClass().getName() + ": " + e.toString(), e); } } } // Rewrite the R 'constants' for all library apks. SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers(); final int N = packageIdentifiers.size(); for (int i = 0; i < N; i++) { final int id = packageIdentifiers.keyAt(i); if (id == 0x01 || id == 0x7f) { continue; } rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id); } Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); return app; }
static public Application newApplication(Class<?> clazz, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { Application app = (Application)clazz.newInstance(); //在這里將applicationContext設置到application對象中 app.attach(context); return app; }
第一階段,Application的創建與初始化已經至此結束,接下來我們將目光放到ActivityTaskManagerInternal
的attachApplication
方法。
public boolean attachApplication(WindowProcessController wpc) throws RemoteException { synchronized (mGlobalLockWithoutBoost) { return mRootActivityContainer.attachApplication(wpc); } }
進入了RootActivityContainer
中繼續執行。
boolean attachApplication(WindowProcessController app) throws RemoteException { final String processName = app.mName; boolean didSomething = false; for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ActivityDisplay display = mActivityDisplays.get(displayNdx); final ActivityStack stack = display.getFocusedStack(); if (stack != null) { stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList); final ActivityRecord top = stack.topRunningActivityLocked(); final int size = mTmpActivityList.size(); for (int i = 0; i < size; i++) { final ActivityRecord activity = mTmpActivityList.get(i); if (activity.app == null && app.mUid == activity.info.applicationInfo.uid && processName.equals(activity.processName)) { try { if (mStackSupervisor.realStartActivityLocked(activity, app, top == activity /* andResume */, true /* checkConfig */)) { didSomething = true; } } catch (RemoteException e) { Slog.w(TAG, "Exception in new application when starting activity " + top.intent.getComponent().flattenToShortString(), e); throw e; } } } } } if (!didSomething) { ensureActivitiesVisible(null, 0, false /* preserve_windows */); } return didSomething; }
由ActivityStackSupervisor
的realStartActivityLocked
方法去真正準備啟動Activity。
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig) throws RemoteException { ... try { ... try { ... // Create activity launch transaction. final ClientTransaction clientTransaction = ClientTransaction.obtain( proc.getThread(), r.appToken); final DisplayContent dc = r.getDisplay().mDisplayContent; clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), 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, proc.getReportedProcState(), r.icicle, r.persistentState, results, newIntents, dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(), r.assistToken)); // Set desired final state. final ActivityLifecycleItem lifecycleItem; if (andResume) { lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward()); } else { lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); // Schedule transaction. mService.getLifecycleManager().scheduleTransaction(clientTransaction); ... } catch (RemoteException e) { ... } } finally { endDeferResume(); } ... return true; }
為了解釋清楚上述過程,我們必須先得認識一下ClientTransaction
及其一系列相關的類。
相關聯的類有以下幾個:ClientTransaction
、TransactionExecutor
、ClientLifecycleManager
以及LaunchActivityItem
,我們一個一個來分析。
LaunchActivityItem
實現了BaseClientRequest
interface。這個接口里定義了三個十分重要的方法。
preExecute 在請求前進行預處理
execute 執行請求
postExecute 執行請求后的后續處理 這種設計方式是不是很眼熟!AsyncTask
也是基于這種模式設計的,各位讀者不妨自行聯想類比一下。
LaunchActivityItem
這個類設計的目的是什么呢?從名字上來講,我們很容易想到,它主要的作用就是用來啟動一個Activity的,具體反應在它重載的excute
方法。
@Override public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState, mPendingResults, mPendingNewIntents, mIsForward, mProfilerInfo, client, mAssistToken); client.handleLaunchActivity(r, pendingActions, null /* customIntent */); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); }
看到這句話了么,client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
。client
這個對象是什么?我們可以翻閱一下代碼的調用鏈,可以發現client
是一個ActivityThread
對象,它最終調用的是ActivityThread
中的handleLaunchActivity
方法。
除了LauncherActivityItem
以外,我們還有abstract的ActivityLifecycleItem
類,在這個類中定義了一系列的生命周期狀態,具體如下:
public static final int UNDEFINED = -1; public static final int PRE_ON_CREATE = 0; public static final int ON_CREATE = 1; public static final int ON_START = 2; public static final int ON_RESUME = 3; public static final int ON_PAUSE = 4; public static final int ON_STOP = 5; public static final int ON_DESTROY = 6; public static final int ON_RESTART = 7;
這些狀態的值基本按照Activity的生命周期的順序,以1為步長遞增定義。為什么這么設計,我們后續會講到。
除此之外,系統還定義了StopActivityItem
、NewIntentItem
、DestroyActivityItem
等等一系列類似的類,這些類都是為了實現具體的和Activity生命周期有關的任務,并按照 預處理——執行——事后處理 的模板編寫業務。
除此之外,這些類其中有一部分還有一個作用,就是確定客戶端在執行事務后最終應處于的生命周期狀態。
生命周期管理類,它能夠組合多個客戶端生命周期變換的請求或回調事務,并將它們作為單個事務執行。這個方法里的內容非常簡單,我們主要來關注一下它的scheduleTransaction
的方法。
void scheduleTransaction(ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient(); transaction.schedule(); if (!(client instanceof Binder)) { // If client is not an instance of Binder - it's a remote call and at this point it is // safe to recycle the object. All objects used for local calls will be recycled after // the transaction is executed on client in ActivityThread. transaction.recycle(); }
根據上述源碼,可以看出它調用了傳入的ClientTransaction
的schedule
方法。
ClientTransaction
是一個保存可以發送到客戶端的消息序列的容器。它包含了三個比較重要的方法, setLifecycleStateRequest
、addCallback
、schedule
,分別用于設置目標生命周期狀態和事務方法,以及執行事務。
我們來看一下schedule
這個方法:
public void schedule() throws RemoteException { mClient.scheduleTransaction(this); }
代碼的內容非常簡單,它將schedule
的操作重新分發給了mClient
變量,這里的mClient
,指的是ActivityThread
實例。
public void executeTransaction(ClientTransaction transaction) { transaction.preExecute(this); getTransactionExecutor().execute(transaction); transaction.recycle(); }
這里首先調用了這樣一條語句,transaction.preExecute(this)
,用于執行事務前的預處理操作。
public void preExecute(android.app.ClientTransactionHandler clientTransactionHandler) { if (mActivityCallbacks != null) { final int size = mActivityCallbacks.size(); for (int i = 0; i < size; ++i) { mActivityCallbacks.get(i).preExecute(clientTransactionHandler, mActivityToken); } } if (mLifecycleStateRequest != null) { mLifecycleStateRequest.preExecute(clientTransactionHandler, mActivityToken); } }
可以看到,它實際調用了通過setLifecycleStateRequest
和addCallback
兩個方法設置進來的對象的preExecute
方法。在實際Activity啟動流程中,對應的是LaunchActivityItem
和ResumeActivityItem
兩個類的preExecute
方法。
TransactionExecutor
是負責管理事務以正確的順序執行的類。
public void execute(ClientTransaction transaction) { ... executeCallbacks(transaction); executeLifecycleState(transaction); mPendingActions.clear(); }
它首先會通過executeCallbacks
方法,執行ClientTransaction
add的所有Callback的execute
和postExecute
方法,具體如下:
public void executeCallbacks(ClientTransaction transaction) { ... //獲取目標生命周期狀態 final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest(); final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState() : UNDEFINED; // Index of the last callback that requests some post-execution state. final int lastCallbackRequestingState = lastCallbackRequestingState(transaction); final int size = callbacks.size(); for (int i = 0; i < size; ++i) { ... item.execute(mTransactionHandler, token, mPendingActions); item.postExecute(mTransactionHandler, token, mPendingActions); ... } }
讓我們回到Activity的啟動流程的代碼中,clientTransaction
加入了一個Callback————LaunchActivityItem
,從上文可以知,這個類的execute
方法里有這么一段代碼client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
,去負責啟動Activity。
private void executeLifecycleState(ClientTransaction transaction) { final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest(); final IBinder token = transaction.getActivityToken(); final ActivityClientRecord r = mTransactionHandler.getActivityClient(token); if (r == null) { //第一次啟動獲得的r為null,實際上會走此分支,只有在performLaunchActivity方法調用后,r才不為null return; } // Cycle to the state right before the final requested state. cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction); // Execute the final transition with proper parameters. lifecycleItem.execute(mTransactionHandler, token, mPendingActions); lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions); }
我們重點關注一下cycleToPath
方法:
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState, ClientTransaction transaction) { final int start = r.getLifecycleState(); if (DEBUG_RESOLVER) { Slog.d(TAG, tId(transaction) + "Cycle activity: " + getShortActivityName(r.token, mTransactionHandler) + " from: " + getStateName(start) + " to: " + getStateName(finish) + " excludeLastState: " + excludeLastState); } final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState); performLifecycleSequence(r, path, transaction); }
mHelper.getLifecyclePath(start, finish, excludeLastState)
:根據當前Activity所處的狀態與目標生命周期狀態,生成一個包含該狀態區間內所有狀態的Int數組。
private void performLifecycleSequence(ActivityClientRecord r, IntArray path, ClientTransaction transaction) { final int size = path.size(); for (int i = 0, state; i < size; i++) { state = path.get(i); if (DEBUG_RESOLVER) { Slog.d(TAG, tId(transaction) + "Transitioning activity: " + getShortActivityName(r.token, mTransactionHandler) + " to state: " + getStateName(state)); } switch (state) { case ON_CREATE: mTransactionHandler.handleLaunchActivity(r, mPendingActions, null /* customIntent */); break; case ON_START: mTransactionHandler.handleStartActivity(r, mPendingActions); break; case ON_RESUME: mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */, r.isForward, "LIFECYCLER_RESUME_ACTIVITY"); break; case ON_PAUSE: mTransactionHandler.handlePauseActivity(r.token, false /* finished */, false /* userLeaving */, 0 /* configChanges */, mPendingActions, "LIFECYCLER_PAUSE_ACTIVITY"); break; case ON_STOP: mTransactionHandler.handleStopActivity(r.token, false /* show */, 0 /* configChanges */, mPendingActions, false /* finalStateRequest */, "LIFECYCLER_STOP_ACTIVITY"); break; case ON_DESTROY: mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */, 0 /* configChanges */, false /* getNonConfigInstance */, "performLifecycleSequence. cycling to:" + path.get(size - 1)); break; case ON_RESTART: mTransactionHandler.performRestartActivity(r.token, false /* start */); break; default: throw new IllegalArgumentException("Unexpected lifecycle state: " + state); } } }
performLifecycleSequence
開始負責按順序執行IntArray區間里的狀態變換。
讓我們重新回到Activity的啟動流程上,從handleLaunchActivity
繼續往下追蹤:
public Activity handleLaunchActivity(ActivityClientRecord r, ... final Activity a = performLaunchActivity(r, customIntent); ... }
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE); } ComponentName component = r.intent.getComponent(); if (component == null) { component = r.intent.resolveActivity( mInitialApplication.getPackageManager()); r.intent.setComponent(component); } if (r.activityInfo.targetActivity != null) { component = new ComponentName(r.activityInfo.packageName, r.activityInfo.targetActivity); } ContextImpl appContext = createBaseContextForActivity(r); Activity activity = null; try { java.lang.ClassLoader cl = appContext.getClassLoader(); //通過newInstance創建Activity實例 activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent); StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); r.intent.prepareToEnterProcess(); if (r.state != null) { r.state.setClassLoader(cl); } } catch (Exception e) { if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException( "Unable to instantiate activity " + component + ": " + e.toString(), e); } } try { Application app = r.packageInfo.makeApplication(false, mInstrumentation); if (localLOGV) Slog.v(TAG, "Performing launch of " + r); if (localLOGV) Slog.v( TAG, r + ": app=" + app + ", appName=" + app.getPackageName() + ", pkg=" + r.packageInfo.getPackageName() + ", comp=" + r.intent.getComponent().toShortString() + ", dir=" + r.packageInfo.getAppDir()); if (activity != null) { CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mCompatConfiguration); if (r.overrideConfig != null) { config.updateFrom(r.overrideConfig); } if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " + r.activityInfo.name + " with config " + config); Window window = null; if (r.mPendingRemoveWindow != null && r.mPreserveWindow) { window = r.mPendingRemoveWindow; r.mPendingRemoveWindow = null; r.mPendingRemoveWindowManager = null; } appContext.setOuterContext(activity); //調用attach方法,開始初始化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, r.assistToken); if (customIntent != null) { activity.mIntent = customIntent; } r.lastNonConfigurationInstances = null; checkAndBlockForNetworkAccess(); activity.mStartedActivity = false; int theme = r.activityInfo.getThemeResource(); if (theme != 0) { activity.setTheme(theme); } activity.mCalled = false; if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { //調用Activity的onCreate方法 mInstrumentation.callActivityOnCreate(activity, r.state); } if (!activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onCreate()"); } r.activity = activity; } r.setState(ON_CREATE); // updatePendingActivityConfiguration() reads from mActivities to update // ActivityClientRecord which runs in a different thread. Protect modifications to // mActivities to avoid race. synchronized (mResourcesManager) { mActivities.put(r.token, r); } } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException( "Unable to start activity " + component + ": " + e.toString(), e); } } return activity; }
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
有些讀者可能會對這句話有些疑問,前面不是已經創建過Application對象了嗎,怎么這里還調用一遍,不是說一個進程里只能有一個Application對象嗎?
我們進入makeApplication
方法里看一下,第一句話就解釋了原因:
if (mApplication != null) { return mApplication; }
所以說,并不會重復創建,這里只是將之前已創建的Application重新獲取一下而已。
mInstrumentation.callActivityOnCreate(activity, r.state);
語句的調用,標識著Activity進入onCreate流程,接下來便是Ui的繪制與展示的流程,在此便不做展開分析了。
文章的最后,我們用一個簡單的圖表對這一篇activity的啟動流程做一個總結,并留給各位讀者一個面試中高頻次問題:請簡述一下Activity的啟動流程? 看看各位讀者能不能總結歸納出一個比較好的答案。
[ActivityThread.java] main() attach() | [ActivityManagerService.java] attachApplication() attachApplicationLocked() | | | [ActivityThread.java] | bindApplication() //發送了H.BIND_APPLICATION消息 | handleBindApplication() //創建Application實例,并調用onCreate方法 | | | [LoadedApk.java] | makeApplication() [ActivityTaskManagerService.java] attachApplication() | [RootActivityContainer.java] attachApplication() | [ActivityStackSupervisor.java] realStartActivityLocked() | [ClientLifecycleManager.java] scheduleTransaction() | [ClientTransaction.java] schedule() | [ActivityThread.java] executeTransaction() | [TransactionExecutor.java] execute() executeCallbacks() | [LaunchActivityItem.java] execute() | [ActivityThread.java] handleLaunchActivity() performLaunchActivity() //創建Activity實例,調用activity attach和onCreate方法
讀到這里,這篇“Android App啟動Activity的方法是什么”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。