日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android Application创建到Activity启动(launcher启动和startActivity启动)

發布時間:2023/12/18 Android 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android Application创建到Activity启动(launcher启动和startActivity启动) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

      • 點擊桌面應用程序創建application和activity流程
      • 點擊 startActivity() 時的調用流程
      • 問題: 為什么啟動時會先調用棧頂activity的onPause()
      • 問題:為什么requestWindowFeature(Window.FEATURE_NO_TITLE);要在setContentView()之前.

點擊桌面應用程序創建application和activity流程

  • 首先從APP程序入口啟動 main 函數開始。看下 ActivityThread 的 main 方法
    main方法中做了一些 Loop 的初始化,Application綁定流程的調用等,具體看代碼:代碼中有備注,省略了部分代碼
public static void main(String[] args) {// ... 省略上面代碼// 內部是初始化 main Looper 邏輯 涉及到 Handler 的初始化知識Looper.prepareMainLooper();// ... 省略上面代碼// 創建 ActivityThread 對象ActivityThread thread = new ActivityThread();// 調用 ActivityThread 的 attach 方法 // attach 方法內部 創建 Instrumentation 對象,綁定 application ,創建 applicationContext 對象,回調 application 的 onCreate 方法// 下面會介紹一下 attach 的源碼thread.attach(false, startSeq);if (sMainThreadHandler == null) {sMainThreadHandler = thread.getHandler();}if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, "ActivityThread"));}// End of event ActivityThreadMain.Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);// 調用 Looper.loop() 內部開啟了 for(;;) 去不斷接受 Handler 發送的消息Looper.loop();throw new RuntimeException("Main thread loop unexpectedly exited");}
  • activityThread 的 attach 方法
    創建 Instrumentation 對象,綁定 application ,創建 applicationContext 對象,回調 application 的 onCreate 方法
private void attach(boolean system, long startSeq) {// ... 代碼省略if (!system) { // 默認傳入的是 false// 通過 Binder機制 ActivityManager.getService(); 獲取 ActivityManagerServicefinal IActivityManager mgr = ActivityManager.getService();try {// 綁定 attachApplication 下一部分會介紹具體綁定流程mgr.attachApplication(mAppThread, startSeq);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}// ...} else {// ... }// 代碼省略...ViewRootImpl.addConfigCallback(configChangedCallback);}
  • 上面 attach 中 mgr.attachApplication(mAppThread, startSeq); 方法是怎么綁定 application 的。進入 ActivityManagerService 的 attachApplication
@Overridepublic final void attachApplication(IApplicationThread thread, long startSeq) {synchronized (this) {// 通過 Binder 獲取 PID ,PID和UID都是進程創建應用的時候系統指定的int callingPid = Binder.getCallingPid();// 獲取 UID final int callingUid = Binder.getCallingUid();final long origId = Binder.clearCallingIdentity();// 最終調用到了 attachApplicationLockedattachApplicationLocked(thread, callingPid, callingUid, startSeq);Binder.restoreCallingIdentity(origId);}}
  • ActivityManagerService 的 attachApplicationLocked(thread, callingPid, callingUid, startSeq);
    這里只挑一些主要代碼去貼出來
@GuardedBy("this")private final boolean attachApplicationLocked(IApplicationThread thread,int pid, int callingUid, long startSeq) {// ProcessRecord AMS通過ProcessRecord來維護進程運行時的信息ProcessRecord app;long startTime = SystemClock.uptimeMillis();// 判斷 pid 和 uid 是否存在則創建 ProcessRecordif (pid != MY_PID && pid >= 0) {synchronized (mPidsSelfLocked) {app = mPidsSelfLocked.get(pid);}} else {app = null;}// ... 代碼省略一大堆// 在下面就是調用 thread.bindApplication 這里的 thread 是 IapplicationThreadif (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 (app.instr != null) {// bindApplication 傳入了各種app相關的信息 下面看 bindApplication 是怎么綁定的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, isAutofillCompatEnabled);} else {thread.bindApplication(processName, appInfo, providers, null, profilerInfo,null, null, null, testMode,mBinderTransactionTrackingEnabled, enableTrackAllocation,isRestrictedBackupMode || !normalMode, app.persistent,new Configuration(getGlobalConfiguration()), app.compat,getCommonServicesLocked(app.isolated),mCoreSettingsObserver.getCoreSettingsLocked(),buildSerial, isAutofillCompatEnabled);}// ... 代碼省略// 做檢測 查看頂部可見活動是否等待此進程中進行if (normalMode) {try {// 后面會介紹 里面會具體解鎖 activity 的創建運行if (mStackSupervisor.attachApplicationLocked(app)) {didSomething = true;}} catch (Exception e) {Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);badApp = true;}}// ... 下面代碼省略}
  • thread.bindApplication 方法。IApplicationThread 中
    經過一系列的操作 最后把各種信息保存在了 AppBindData 中,它就是javabean,最后調用了
    sendMessage(H.BIND_APPLICATION, data);
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, boolean autofillCompatibilityEnabled) {if (services != null) {if (false) {// Test code to make sure the app could see the passed-in services.for (Object oname : services.keySet()) {if (services.get(oname) == null) {continue; // AM just passed in a null service.}String name = (String) oname;// See b/79378449 about the following exemption.switch (name) {case "package":case Context.WINDOW_SERVICE:continue;}if (ServiceManager.getService(name) == null) {Log.wtf(TAG, "Service " + name + " should be accessible by this app");}}}// Setup the service cache in the ServiceManagerServiceManager.initServiceCache(services);}setCoreSettings(coreSettings);// 將各種數據保存下載AppBindData data = new AppBindData();data.processName = processName;data.appInfo = appInfo;data.providers = providers;data.instrumentationName = instrumentationName;data.instrumentationArgs = instrumentationArgs;data.instrumentationWatcher = instrumentationWatcher;data.instrumentationUiAutomationConnection = instrumentationUiConnection;data.debugMode = debugMode;data.enableBinderTracking = enableBinderTracking;data.trackAllocation = trackAllocation;data.restrictedBackupMode = isRestrictedBackupMode;data.persistent = persistent;data.config = config;data.compatInfo = compatInfo;data.initProfilerInfo = profilerInfo;data.buildSerial = buildSerial;data.autofillCompatibilityEnabled = autofillCompatibilityEnabled;// 發送handler消息sendMessage(H.BIND_APPLICATION, data);}
  • 接下來看看 Handler 接收 H.BIND_APPLICATION 消息是怎么處理的。
public void handleMessage(Message msg) {if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));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;
  • ActivityThread 中的 handleBindApplication(data);
private void handleBindApplication(AppBindData data) {// ... 只貼出主要代碼try {// If the app is being launched for full backup or restore, bring it up in// 創建 applicationapp = data.info.makeApplication(data.restrictedBackupMode, null);// Propagate autofill compat stateapp.setAutofillCompatibilityEnabled(data.autofillCompatibilityEnabled);mInitialApplication = app;// don't bring up providers in restricted mode; they may depend on the// app's custom Application classif (!data.restrictedBackupMode) {if (!ArrayUtils.isEmpty(data.providers)) {installContentProviders(app, data.providers);// For process that contains content providers, we want to// ensure that the JIT is enabled "at some point".mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);}}// 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 {// 調用 appilcation 的 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/36951662if (data.appInfo.targetSdkVersion < Build.VERSION_CODES.O_MR1|| StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) {StrictMode.setThreadPolicy(savedPolicy);}}}
  • 上面代碼中 app = data.info.makeApplication(data.restrictedBackupMode, null);
    LoadedApk 中的 makeApplication
public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {if (mApplication != null) {return mApplication;}Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");Application app = null;// 獲取 application的 calssName 這里面是獲取的自定義 application 的名字 如果沒有則引用系統默認的String appClass = mApplicationInfo.className;if (forceDefaultAppClass || (appClass == null)) {appClass = "android.app.Application";}try {// 通過 calssLoader 來創建 applicationjava.lang.ClassLoader cl = getClassLoader();if (!mPackageName.equals("android")) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,"initializeJavaContextClassLoader");initializeJavaContextClassLoader();Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);}// 創建 applicationContexxtContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);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 {// 調用 onCreateinstrumentation.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;}
  • 這樣 application 就創建完成了 ,然后繼續回到 ActivityManagerService 中的 attachApplicationLocked 創建完成application之后繼續執行后面的代碼,有這么一句話
mStackSupervisor.attachApplicationLocked(app)
  • 來具體看看里面是做什么的
    ActivityStackSupervisor 的 attachApplicationLocked
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {// 獲取進程名final String processName = app.processName;boolean didSomething = false;for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {final ActivityStack stack = display.getChildAt(stackNdx);if (!isFocusedStack(stack)) {continue;}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.uid == activity.info.applicationInfo.uid&& processName.equals(activity.processName)) {try {// 下面會看一下 realStartActivityLocked 里面是什么邏輯if (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) {ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);}return didSomething;}
  • ActivityStackSupervisor 的 realStartActivityLocked
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException {// ... // Create activity launch transaction.final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,r.appToken);// LaunchActivityItem 就是 manifest里面的 launch回調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, app.repProcState, r.icicle,r.persistentState, results, newIntents, mService.isNextTransitionForward(),profilerInfo));}// Set desired final state.final ActivityLifecycleItem lifecycleItem;if (andResume) {lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());} else {lifecycleItem = PauseActivityItem.obtain();}clientTransaction.setLifecycleStateRequest(lifecycleItem);// Schedule transaction.// 調用 scheduleTransaction 代碼在下面會貼出來 mService 就是 AMSmService.getLifecycleManager().scheduleTransaction(clientTransaction);
  • mService.getLifecycleManager().scheduleTransaction(clientTransaction); 方法
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 中的 transaction.schedule();
public void schedule() throws RemoteException {// 調用了 IApplicationThread 的 scheduleTransactionmClient.scheduleTransaction(this);}
  • mClient.scheduleTransaction(this); 調用到了 ActivityThread 中的
@Overridepublic void scheduleTransaction(ClientTransaction transaction) throws RemoteException {ActivityThread.this.scheduleTransaction(transaction);}
  • ActivityThread.this.scheduleTransaction(transaction); 如下:
/** Prepare and schedule transaction for execution. */void scheduleTransaction(ClientTransaction transaction) {transaction.preExecute(this);// 發送 HandlersendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);}
  • 看一下 Handler 的 EXECUTE_TRANSACTION
case EXECUTE_TRANSACTION:final ClientTransaction transaction = (ClientTransaction) msg.obj;mTransactionExecutor.execute(transaction);if (isSystem()) {// Client transactions inside system process are recycled on the client side// instead of ClientLifecycleManager to avoid being cleared before this// message is handled.transaction.recycle();}// TODO(lifecycler): Recycle locally scheduled transactions.break;
  • 上面 Handler 中 mTransactionExecutor.execute(transaction); 跳轉到 TransactionExecutor 中
public void execute(ClientTransaction transaction) {final IBinder token = transaction.getActivityToken();log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);// 調用這個方法executeCallbacks(transaction); executeLifecycleState(transaction);mPendingActions.clear();log("End resolving transaction");}
  • executeCallbacks(transaction); 方法
public void executeCallbacks(ClientTransaction transaction) {final List<ClientTransactionItem> callbacks = transaction.getCallbacks();if (callbacks == null) {// No callbacks to execute, return early.return;}log("Resolving callbacks");final IBinder token = transaction.getActivityToken();ActivityClientRecord r = mTransactionHandler.getActivityClient(token);// In case when post-execution state of the last callback matches the final state requested// for the activity in this transaction, we won't do the last transition here and do it when// moving to final state instead (because it may contain additional parameters from server).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) {final ClientTransactionItem item = callbacks.get(i);log("Resolving callback: " + item);final int postExecutionState = item.getPostExecutionState();final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,item.getPostExecutionState());if (closestPreExecutionState != UNDEFINED) {cycleToPath(r, closestPreExecutionState);}// 執行了 item.execute 就是 LaunchActivityItem 的 executeitem.execute(mTransactionHandler, token, mPendingActions);item.postExecute(mTransactionHandler, token, mPendingActions);if (r == null) {// Launch activity request will create an activity record.r = mTransactionHandler.getActivityClient(token);}if (postExecutionState != UNDEFINED && r != null) {// Skip the very last transition and perform it by explicit state request instead.final boolean shouldExcludeLastTransition =i == lastCallbackRequestingState && finalState == postExecutionState;cycleToPath(r, postExecutionState, shouldExcludeLastTransition);}}}
  • 上面的 item.execute 就是 LaunchActivityItem 的 execute
@Overridepublic 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);// 調用了 handleLaunchActivity 這句話又回到了 ActivityThread中的 handleLaunchActivityclient.handleLaunchActivity(r, pendingActions, null /* customIntent */);Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);}
@Overridepublic Activity handleLaunchActivity(ActivityClientRecord r,PendingTransactionActions pendingActions, Intent customIntent) {// ... // 得到 activity 對象final Activity a = performLaunchActivity(r, customIntent);if (a != null) {r.createdConfig = new Configuration(mConfiguration);reportSizeConfigurations(r);if (!r.activity.mFinished && pendingActions != null) {pendingActions.setOldState(r.state);pendingActions.setRestoreInstanceState(true);pendingActions.setCallOnPostCreate(true);}} else {// If there was an error, for any reason, tell the activity manager to stop us.try {ActivityManager.getService().finishActivity(r.token, Activity.RESULT_CANCELED, null,Activity.DONT_FINISH_TASK_WITH_ACTIVITY);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}return a;}
  • performLaunchActivity(r, customIntent);
/** Core implementation of activity launch. */private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {// 通過 ClassLoader 創建 newActivityContextImpl appContext = createBaseContextForActivity(r);Activity activity = null;try {java.lang.ClassLoader cl = appContext.getClassLoader();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);}}// ... // ...Window window = null;if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {window = r.mPendingRemoveWindow;r.mPendingRemoveWindow = null;r.mPendingRemoveWindowManager = null;}appContext.setOuterContext(activity);// 調用 activity 的attach 方法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 (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;// 這里面調用了 mInstrumentation.callActivityOnCreate if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {mInstrumentation.callActivityOnCreate(activity, r.state);}// ...// ...r.setState(ON_CREATE);// ...// ...}
  • mInstrumentation.callActivityOnCreate
public void callActivityOnCreate(Activity activity, Bundle icicle) {// 調用了 activity.performCreateprePerformCreate(activity);activity.performCreate(icicle);postPerformCreate(activity);}
  • 在 performLaunchActivity 中調用了 callActivityOnCreate 后,調用了 r.setState(ON_CREATE); 方法 記錄了當前是 onCreate狀態(實際上保存的就是int值 1-7)
    然后前面在 TransactionExecuor調用了 executeCallbacks(transaction); 之后會繼續調用
    executeLifecycleState(transaction);

  • executeLifecycleState

private void executeLifecycleState(ClientTransaction transaction) {// ...// Cycle to the state right before the final requested state.// 這里會繼續根據state調用其他的生命周期cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);// Execute the final transition with proper parameters.lifecycleItem.execute(mTransactionHandler, token, mPendingActions);lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);}
  • cycleToPath 然后調用 performLifecycleSequence()
private void cycleToPath(ActivityClientRecord r, int finish,boolean excludeLastState) {final int start = r.getLifecycleState();log("Cycle from: " + start + " to: " + finish + " excludeLastState:" + excludeLastState);final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);performLifecycleSequence(r, path);}/** Transition the client through previously initialized state sequence. */private void performLifecycleSequence(ActivityClientRecord r, IntArray path) {final int size = path.size();for (int i = 0, state; i < size; i++) {state = path.get(i);log("Transitioning to state: " + 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);}}}

其中的mTransactionHandler 就是 ThreadHandler ,又回到了ThreadHandler中繼續下面的生命周期調用。

點擊 startActivity() 時的調用流程

  • 調用 startActivity(new Intent()); 方法。
    隨著調用會調用到 startActivityForResult
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {// 重點代碼 調用了 Instrumentation 的 execStartActivitymInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);}
  • Instrumentation 的 execStartActivity
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, String resultWho,Intent intent, int requestCode, Bundle options, UserHandle user) {// 重要代碼 調用了 AMS 的 startActivityAsUser 方法int result = ActivityManager.getService().startActivityAsUser(whoThread, who.getBasePackageName(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()),token, resultWho,requestCode, 0, null, options, user.getIdentifier());}
  • AMS 的 startActivityAsUser 方法
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,boolean validateIncomingUser) {enforceNotIsolatedCaller("startActivity");userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");// 這里面保存了一些信息 比如熟悉的 requestCode userId 等等 // 執行的 execute 是調用到了 ActivityStarter 的 execute() 方法return mActivityStartController.obtainStarter(intent, "startActivityAsUser").setCaller(caller).setCallingPackage(callingPackage).setResolvedType(resolvedType).setResultTo(resultTo).setResultWho(resultWho).setRequestCode(requestCode).setStartFlags(startFlags).setProfilerInfo(profilerInfo).setActivityOptions(bOptions).setMayWait(userId).execute();}
  • ActivityStarter 的 execute() 方法
int execute() {try {// TODO(b/64750076): Look into passing request directly to these methods to allow// 上面傳進來的默認是 true 所以后面調用的是 startActivityMayWaitif (mRequest.mayWait) {return startActivityMayWait(mRequest.caller, mRequest.callingUid,mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,mRequest.inTask, mRequest.reason,mRequest.allowPendingRemoteAnimationRegistryLookup);} else {return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,mRequest.ignoreTargetSecurity, mRequest.componentSpecified,mRequest.outActivity, mRequest.inTask, mRequest.reason,mRequest.allowPendingRemoteAnimationRegistryLookup);}} finally {onExecutionComplete();}}
  • ActivityStarter 的 startActivityMayWait() 方法
private 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, SafeActivityOptions options, boolean ignoreTargetSecurity,int userId, TaskRecord inTask, String reason,boolean allowPendingRemoteAnimationRegistryLookup) {// ... 重要代碼int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,allowPendingRemoteAnimationRegistryLookup);}
  • ActivityStarter 的 startActivity() 方法
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,// .... // 調用了重載的 startActivity mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,inTask, allowPendingRemoteAnimationRegistryLookup);if (outActivity != null) {// mLastStartActivityRecord[0] is set in the call to startActivity above.outActivity[0] = mLastStartActivityRecord[0];}return getExternalResult(mLastStartActivityResult);}
  • ActivityStarter 的 startActivity() 方法
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,SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,ActivityRecord[] outActivity, TaskRecord inTask, String reason,boolean allowPendingRemoteAnimationRegistryLookup) {// ...// ...// 再一次調用了重載的方法return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,true /* doResume */, checkedOptions, inTask, outActivity);}
  • ActivityStarter 的 startActivity() 方法
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity) {int result = START_CANCELED;try {mService.mWindowManager.deferSurfaceLayout();// 調用了 startActivityUnchecked 方法result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,startFlags, doResume, options, inTask, outActivity);} finally {// ...mService.mWindowManager.continueSurfaceLayout();}postStartActivityProcessing(r, result, mTargetStack);return result;}
  • startActivityUnchecked() 方法
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,ActivityRecord[] outActivity) {// ...// 調用到了 ActivityStackSupervisor 中的 resumeFocusedStackTopActivityLockedmSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,mOptions);mOptions);// ... }
  • ActivityStackSupervisor 中的 resumeFocusedStackTopActivityLocked
boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {if (!readyToResume()) {return false;}if (targetStack != null && isFocusedStack(targetStack)) {return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);}final ActivityRecord r = mFocusedStack.topRunningActivityLocked();if (r == null || !r.isState(RESUMED)) {mFocusedStack.resumeTopActivityUncheckedLocked(null, null);} else if (r.isState(RESUMED)) {// Kick off any lingering app transitions form the MoveTaskToFront operation.mFocusedStack.executeAppTransition(targetOptions);}return false;}
  • mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {if (mStackSupervisor.inResumeTopActivity) {// Don't even start recursing.return false;}boolean result = false;try {// Protect against recursion.mStackSupervisor.inResumeTopActivity = true;// 調用 resumeTopActivityInnerLocked result = resumeTopActivityInnerLocked(prev, options);final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);if (next == null || !next.canTurnScreenOn()) {checkReadyForSleep();}} finally {mStackSupervisor.inResumeTopActivity = false;}return result;}

經過一些列的調用會走到 ActivityStachSupervisor 中下面的方法

  • startSpecificActivityLocked
void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) {// Is this activity's application already running?ProcessRecord app = mService.getProcessRecordLocked(r.processName,r.info.applicationInfo.uid, true);getLaunchTimeTracker().setLaunchTime(r);// 先判斷進程 是否存在 如果進程存在則調用 realStartActivityLockedif (app != null && app.thread != null) {try {realStartActivityLocked(r, app, andResume, checkConfig);return;}}// 如果進程不存在則通過 AMS 去開啟進程創建流程mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,"activity", r.intent.getComponent(), false, false, true);}
  • realStartActivityLocked()
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException {mService.getLifecycleManager().scheduleTransaction(clientTransaction);} 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();

private IApplicationThread mClient;public void schedule() throws RemoteException {// 這里實際上調用到了當前客戶端的 ApplicationThread 的 scheduleTransaction()mClient.scheduleTransaction(this);}
  • scheduleTransaction()
@Overridepublic void scheduleTransaction(ClientTransaction transaction) throws RemoteException {ActivityThread.this.scheduleTransaction(transaction);}

ActivityThread.this 中 ActivityThread 并沒有重寫 scheduleTransaction 所以調用的是其父類的ClientTransactionHandler 的 scheduleTransaction() 方法

void scheduleTransaction(ClientTransaction transaction) {transaction.preExecute(this);sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);}

發送了 EXECUTE_TRANSACTION 消息,接收消息在 ActivityThread 中的 handleMessage()

public void handleMessage(Message msg) {switch (msg.what) {case EXECUTE_TRANSACTION:final ClientTransaction transaction = (ClientTransaction) msg.obj;mTransactionExecutor.execute(transaction);if (isSystem()) {// Client transactions inside system process are recycled on the client side// instead of ClientLifecycleManager to avoid being cleared before this// message is handled.transaction.recycle();}// TODO(lifecycler): Recycle locally scheduled transactions.break;} }

// 執行了 LaunchActivityItem 的 execute LaunchActivityItemClientTransactionItem

public void execute(ClientTransaction transaction) {
// 其內部調用了 executeCallbacks
// 該方法內執行了 LaunchActivityItem 的 execute
executeCallbacks(transaction);
}

@Overridepublic 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);// client 是 ClientTransactionHandler 它的實現類是 ActivityThreadclient.handleLaunchActivity(r, pendingActions, null /* customIntent */);Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);}

所以接下來就到了 ActivityThread 中的 handleLaunchActivity 流程,啟動Activity 執行生命周期

問題: 為什么啟動時會先調用棧頂activity的onPause()

  • resumeTopActivityInnerLocked
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {// startPausingLocked 先讓棧頂的activity去onPause 然后在去啟動新的activity// 所以當啟動一個新的activity的時候會先讓頂部activity onPause 雖然可見但是已經失去焦點// 內部 pause 原理也是通過發送 Handler 然后出發 state 的改變回調if (mResumedActivity != null) {if (DEBUG_STATES) Slog.d(TAG_STATES,"resumeTopActivityLocked: Pausing " + mResumedActivity);pausing |= startPausingLocked(userLeaving, false, next, false);}// ... // 最后調用了 startSpecificActivityLocked 去啟動 activitymStackSupervisor.startSpecificActivityLocked(next, true, false);}
  • startSpecificActivityLocked()
void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) {// Is this activity's application already running?ProcessRecord app = mService.getProcessRecordLocked(r.processName,r.info.applicationInfo.uid, true);getLaunchTimeTracker().setLaunchTime(r);if (app != null && app.thread != null) {try {if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0|| !"android".equals(r.info.packageName)) {// Don't add this if it is a platform component that is marked// to run in multiple processes, because this is actually// part of the framework so doesn't make sense to track as a// separate apk in the process.app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,mService.mProcessStats);}// real startrealStartActivityLocked(r, app, andResume, checkConfig);return;} catch (RemoteException e) {Slog.w(TAG, "Exception when starting activity "+ r.intent.getComponent().flattenToShortString(), e);}// If a dead object exception was thrown -- fall through to// restart the application.}mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,"activity", r.intent.getComponent(), false, false, true);}
  • realStartActivityLocked
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,boolean andResume, boolean checkConfig) throws RemoteException {// ...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, app.repProcState, r.icicle,r.persistentState, results, newIntents, mService.isNextTransitionForward(),profilerInfo));// Set desired final state.final ActivityLifecycleItem lifecycleItem;if (andResume) {lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());} else {lifecycleItem = PauseActivityItem.obtain();}// 設置生命周期的狀態clientTransaction.setLifecycleStateRequest(lifecycleItem);// 執行生命周期的調用mService.getLifecycleManager().scheduleTransaction(clientTransaction);// ... }
  • mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    下面的代碼就和最開始 app啟動的activity啟動差不多了
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();}}
  • 會調用到 scheduleTransaction
void scheduleTransaction(ClientTransaction transaction) {transaction.preExecute(this);sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);}
  • 對應 handler 中
case EXECUTE_TRANSACTION:final ClientTransaction transaction = (ClientTransaction) msg.obj;mTransactionExecutor.execute(transaction);if (isSystem()) {// Client transactions inside system process are recycled on the client side// instead of ClientLifecycleManager to avoid being cleared before this// message is handled.transaction.recycle();}
  • TransactionExecutor 中的 execute 方法。
public void execute(ClientTransaction transaction) {final IBinder token = transaction.getActivityToken();// 指定 callbacksexecuteCallbacks(transaction);executeLifecycleState(transaction);mPendingActions.clear();log("End resolving transaction");}
  • 然后執行executeCallbacks 中的 item.execute(mTransactionHandler, token, mPendingActions);
public void executeCallbacks(ClientTransaction transaction) {// ... // 執行了 LaunchActivityItem 的 execute LaunchActivityItemClientTransactionItemitem.execute(mTransactionHandler, token, mPendingActions);item.postExecute(mTransactionHandler, token, mPendingActions);if (r == null) {// Launch activity request will create an activity record.r = mTransactionHandler.getActivityClient(token);}if (postExecutionState != UNDEFINED && r != null) {// Skip the very last transition and perform it by explicit state request instead.final boolean shouldExcludeLastTransition =i == lastCallbackRequestingState && finalState == postExecutionState;// 通過 cycleToPath 調用后面的生命周期cycleToPath(r, postExecutionState, shouldExcludeLastTransition);}// ...}
  • LaunchActivityItem 的 execute
@Overridepublic 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);// 最終調用回了 ActivityThread 中的 handleLaunchActivityclient.handleLaunchActivity(r, pendingActions, null /* customIntent */);Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);}
  • 接下來 ActivityThread 中的 handleLaunchActivity 后就通過調用 mInstrumentation.newActivity進行創建, activity的attach onCreate方法等進行activity生命周期的開始。下面就不說了跟上面都一樣了。

問題:為什么requestWindowFeature(Window.FEATURE_NO_TITLE);要在setContentView()之前.

  • 我們看一下setContentView的源碼:在 installDecor() 的時候。
@Overridepublic void setContentView(int layoutResID) {if (mContentParent == null) {// 創建DecorinstallDecor();} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {mContentParent.removeAllViews();}if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {// ...} else {mLayoutInflater.inflate(layoutResID, mContentParent);}// ...}
  • 在 installDecor(); 中
private void installDecor() {mForceDecorInstall = false;if (mDecor == null) {// 如果是null new Decor // 當 new Decor()的時候需要傳入 FeatureId 所以要在之前設置好才會能拿到用戶自己設置的值。源碼我就不貼出來了mDecor = generateDecor(-1);// ...} else {mDecor.setWindow(this);}if (mContentParent == null) {// 這里面會獲取 Feature 的信息mContentParent = generateLayout(mDecor);// Set up decor part of UI to ignore fitsSystemWindows if appropriate.mDecor.makeOptionalFitsSystemWindows();final DecorContentParent decorContentParent = (DecorContentParent) mDecor.findViewById(R.id.decor_content_parent);if (decorContentParent != null) {mDecorContentParent = decorContentParent;mDecorContentParent.setWindowCallback(getCallback());if (mDecorContentParent.getTitle() == null) {mDecorContentParent.setWindowTitle(mTitle);}final int localFeatures = getLocalFeatures();for (int i = 0; i < FEATURE_MAX; i++) {if ((localFeatures & (1 << i)) != 0) {mDecorContentParent.initFeature(i);}}mDecorContentParent.setUiOptions(mUiOptions);if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) != 0 ||(mIconRes != 0 && !mDecorContentParent.hasIcon())) {mDecorContentParent.setIcon(mIconRes);} else if ((mResourcesSetFlags & FLAG_RESOURCE_SET_ICON) == 0 &&mIconRes == 0 && !mDecorContentParent.hasIcon()) {mDecorContentParent.setIcon(getContext().getPackageManager().getDefaultActivityIcon());mResourcesSetFlags |= FLAG_RESOURCE_SET_ICON_FALLBACK;}if ((mResourcesSetFlags & FLAG_RESOURCE_SET_LOGO) != 0 ||(mLogoRes != 0 && !mDecorContentParent.hasLogo())) {mDecorContentParent.setLogo(mLogoRes);}PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);if (!isDestroyed() && (st == null || st.menu == null) && !mIsStartingWindow) {invalidatePanelMenu(FEATURE_ACTION_BAR);}} else {mTitleView = findViewById(R.id.title);if (mTitleView != null) {if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) {final View titleContainer = findViewById(R.id.title_container);if (titleContainer != null) {titleContainer.setVisibility(View.GONE);} else {mTitleView.setVisibility(View.GONE);}mContentParent.setForeground(null);} else {mTitleView.setText(mTitle);}}}if (mDecor.getBackground() == null && mBackgroundFallbackResource != 0) {mDecor.setBackgroundFallback(mBackgroundFallbackResource);}// 判斷 sFeature 的值 if (hasFeature(FEATURE_ACTIVITY_TRANSITIONS)) {if (mTransitionManager == null) {final int transitionRes = getWindowStyle().getResourceId(R.styleable.Window_windowContentTransitionManager,0);if (transitionRes != 0) {final TransitionInflater inflater = TransitionInflater.from(getContext());mTransitionManager = inflater.inflateTransitionManager(transitionRes,mContentParent);} else {mTransitionManager = new TransitionManager();}}mEnterTransition = getTransition(mEnterTransition, null,R.styleable.Window_windowEnterTransition);mReturnTransition = getTransition(mReturnTransition, USE_DEFAULT_TRANSITION,R.styleable.Window_windowReturnTransition);mExitTransition = getTransition(mExitTransition, null,R.styleable.Window_windowExitTransition);mReenterTransition = getTransition(mReenterTransition, USE_DEFAULT_TRANSITION,R.styleable.Window_windowReenterTransition);mSharedElementEnterTransition = getTransition(mSharedElementEnterTransition, null,R.styleable.Window_windowSharedElementEnterTransition);mSharedElementReturnTransition = getTransition(mSharedElementReturnTransition,USE_DEFAULT_TRANSITION,R.styleable.Window_windowSharedElementReturnTransition);mSharedElementExitTransition = getTransition(mSharedElementExitTransition, null,R.styleable.Window_windowSharedElementExitTransition);mSharedElementReenterTransition = getTransition(mSharedElementReenterTransition,USE_DEFAULT_TRANSITION,R.styleable.Window_windowSharedElementReenterTransition);if (mAllowEnterTransitionOverlap == null) {mAllowEnterTransitionOverlap = getWindowStyle().getBoolean(R.styleable.Window_windowAllowEnterTransitionOverlap, true);}if (mAllowReturnTransitionOverlap == null) {mAllowReturnTransitionOverlap = getWindowStyle().getBoolean(R.styleable.Window_windowAllowReturnTransitionOverlap, true);}if (mBackgroundFadeDurationMillis < 0) {mBackgroundFadeDurationMillis = getWindowStyle().getInteger(R.styleable.Window_windowTransitionBackgroundFadeDuration,DEFAULT_BACKGROUND_FADE_DURATION_MS);}if (mSharedElementsUseOverlay == null) {mSharedElementsUseOverlay = getWindowStyle().getBoolean(R.styleable.Window_windowSharedElementsUseOverlay, true);}}}}

所以需要在setContentView之前設置才會生效。

總結

以上是生活随笔為你收集整理的Android Application创建到Activity启动(launcher启动和startActivity启动)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。