标签:ash dstat nothing indent 代码 multi sdk 显示 second
public final void activityPaused(IBinder token) { final long origId = Binder.clearCallingIdentity(); synchronized(this) { ActivityStack stack = ActivityRecord.getStackLocked(token); if (stack != null) { stack.activityPausedLocked(token, false); } } Binder.restoreCallingIdentity(origId); }ActivityStack.class
final void activityPausedLocked(IBinder token, boolean timeout) { if (DEBUG_PAUSE) Slog.v( TAG, "Activity paused: token=" + token + ", timeout=" + timeout); final ActivityRecord r = isInStackLocked(token); if (r != null) { mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r); if (mPausingActivity == r) { if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r + (timeout ?ActivityStack.class" (due to timeout)" : " (pause complete)")); completePauseLocked(true); } else { EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE, r.userId, System.identityHashCode(r), r.shortComponentName, mPausingActivity != null ? mPausingActivity.shortComponentName : "(none)"); } } }
private void completePauseLocked(boolean resumeNext) { ActivityRecord prev = mPausingActivity; if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev); if (prev != null) { //... } if (resumeNext) { final ActivityStack topStack = mStackSupervisor.getFocusedStack(); if (!mService.isSleepingOrShuttingDown()) { mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null); } else { mStackSupervisor.checkReadyForSleepLocked(); ActivityRecord top = topStack.topRunningActivityLocked(null); if (top == null || (prev != null && top != prev)) { // If there are no more activities available to run, // do resume anyway to start something. Also if the top // activity on the stack is not the just paused activity, // we need to go ahead and resume it to ensure we complete // an in-flight app switch. mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null); } } } if (prev != null) { //... } // Notfiy when the task stack has changed mService.notifyTaskStackChangedLocked(); }ActivityStackSupervisor.class
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, Bundle targetOptions) { if (targetStack == null) { targetStack = getFocusedStack(); } // Do targetStack first. boolean result = false; if (isFrontStack(targetStack)) { result = targetStack.resumeTopActivityLocked(target, targetOptions); } for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = stacks.get(stackNdx); if (stack == targetStack) { // Already started above. continue; } if (isFrontStack(stack)) { //调用 ActivityStack.resumeTopActivityLocked(null)方法正式启动目标Activity stack.resumeTopActivityLocked(null); } } } return result; }ActivityStack.class
final boolean resumeTopActivityLocked(ActivityRecord prev) { return resumeTopActivityLocked(prev, null); } final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) { if (mStackSupervisor.inResumeTopActivity) { // Don't even start recursing. return false; } boolean result = false; try { // Protect against recursion. mStackSupervisor.inResumeTopActivity = true; if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) { mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN; mService.updateSleepIfNeededLocked(); } result = resumeTopActivityInnerLocked(prev, options); } finally { mStackSupervisor.inResumeTopActivity = false; } return result; }ActivityStack.class
final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) { if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(""); //... if (next == null) { //... } // If the top activity is the resumed one, nothing to do. if (mResumedActivity == next && next.state == ActivityState.RESUMED && mStackSupervisor.allResumedActivitiesComplete()) { //... } final TaskRecord nextTask = next.task; if (prevTask != null && prevTask.stack == this && prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) { //... } //... ActivityStack lastStack = mStackSupervisor.getLastStack(); if (next.app != null && next.app.thread != null) { //... } else { // Whoops, need to restart this activity! if (!next.hasBeenLaunched) { next.hasBeenLaunched = true; } else { //... } if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Restarting " + next); mStackSupervisor.startSpecificActivityLocked(next, true, true); } if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked(); return true; }假设上面不能直接resume已有的Activity对象。那么接下来就要推断目标Activity相应的进程是否存在。
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // Is this activity's application already running? ////获取目标Activity相应的进程对象ProcessRecord app ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); r.task.stack.setLaunchTime(r); //假设目标Activity所在的app进程已经开启,比方说直接从Activity_A打开Activity_B 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.versionCode, mService.mProcessStats); } realStartActivityLocked(r, app, andResume, checkConfig); //注意:在这里return了 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. } //假设目标Activity所在的app进程还未开启,假设是从Launcher启动一个新的APP,则会调用此句(不会运行上面的if) mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); }Activity_A打开Activity_B会运行if (app != null && app.thread != null) 中的realStartActivityLocked(r, app, andResume, checkConfig),由于已经目标Activity相应的进程已经开启了,事实上启动目标进程之后(mService.startProcessLocked)。还是会调用realStartActivityLocked,这里也顺便去看一看是怎么启动目标进程的。
public static void main(String[] args) { SamplingProfilerIntegration.start(); Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); //... Looper.loop(); //... }调用prepareMainLooper()在 U I线程创建一个消息队列(MessageQueue)。Looper.loop()让消息循环。
final ApplicationThread mAppThread = new ApplicationThread(); final Looper mLooper = Looper.myLooper(); final H mH = new H();前面说过,ApplicationThread它是一个Binder对象,负责接收远程AmS的 IPC 调用,接收到调用后。则通 过Handler把消息发送到消息队列,U I主线程会异步地从消息队列中取出消息并运行对应操作。比方 start、 stop、pause 等 。
private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; if (!system) { //... try { mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore } //... } else { //... } //... ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { //... }); }能够看到,这里 mgr.attachApplication(mAppThread)把ActivityThread初始化时创建的mAppThread作为參数传递过去
@Override public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } }ActivityManagerService.class
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { // Find the application record that is being attached... either via // the pid if we are running in multiple processes, or just pull the // next app record if we are emulating process with anonymous threads. ProcessRecord app; if (pid != MY_PID && pid >= 0) { synchronized (mPidsSelfLocked) { app = mPidsSelfLocked.get(pid); } } else { app = null; } if (app == null) { //... return false; } //... if (localLOGV) Slog.v( TAG, "New app record " + app + " thread=" + thread.asBinder() + " pid=" + pid); try { //... //通过thread.bindApplication调用ActivityThread.handleBindApplication,Binder机制 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(mConfiguration), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked()); updateLruProcessLocked(app, false, null); app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); } catch (Exception e) { //... return false; } //... // See if the top visible activity is waiting to run in this process... if (normalMode) { try { if (mStackSupervisor.attachApplicationLocked(app)) { didSomething = true; } } catch (Exception e) { Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); badApp = true; } } //... return true; }通过thread.bindApplication调用ActivityThread.handleBindApplication,Binder机制
private void handleBindApplication(AppBindData data) { mBoundApplication = data; mConfiguration = new Configuration(data.config); mCompatConfiguration = new Configuration(data.config); //... if (data.instrumentationName != null) { InstrumentationInfo ii = null; try { ii = appContext.getPackageManager(). getInstrumentationInfo(data.instrumentationName, 0); } catch (PackageManager.NameNotFoundException e) { } if (ii == null) { throw new RuntimeException( "Unable to find instrumentation info for: " + data.instrumentationName); } mInstrumentationPackageName = ii.packageName; mInstrumentationAppDir = ii.sourceDir; mInstrumentationSplitAppDirs = ii.splitSourceDirs; mInstrumentationLibDir = ii.nativeLibraryDir; mInstrumentedAppDir = data.info.getAppDir(); mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); mInstrumentedLibDir = data.info.getLibDir(); ApplicationInfo instrApp = new ApplicationInfo(); instrApp.packageName = ii.packageName; instrApp.sourceDir = ii.sourceDir; instrApp.publicSourceDir = ii.publicSourceDir; instrApp.splitSourceDirs = ii.splitSourceDirs; instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs; instrApp.dataDir = ii.dataDir; instrApp.nativeLibraryDir = ii.nativeLibraryDir; LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, appContext.getClassLoader(), false, true, false); ContextImpl instrContext = ContextImpl.createAppContext(this, pi); try { java.lang.ClassLoader cl = instrContext.getClassLoader(); //Instrumentation的初始化,一个应用程序中仅仅有一个Instrumentation对象,每一个Activity内部都有一个该对象的引用,初始化完毕之后。帮助管理Activity生命周期的回调。 mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate instrumentation " + data.instrumentationName + ": " + e.toString(), e); } mInstrumentation.init(this, instrContext, appContext, new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher, data.instrumentationUiAutomationConnection); //... } else { mInstrumentation = new Instrumentation(); } if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); } // Allow disk access during application and provider setup. This could // block processing ordered broadcasts, but later processing would // probably end up doing the same disk access. final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); try { //... // Do this after providers, since instrumentation tests generally start their // test thread at this point, and we don't want that racing. try { //App 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 { StrictMode.setThreadPolicy(savedPolicy); } }
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { final String processName = app.processName; boolean didSomething = false; for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = stacks.get(stackNdx); if (!isFrontStack(stack)) { continue; } ActivityRecord hr = stack.topRunningActivityLocked(null); if (hr != null) { if (hr.app == null && app.uid == hr.info.applicationInfo.uid && processName.equals(hr.processName)) { try { //调用了realStartActivityLocked if (realStartActivityLocked(hr, app, true, true)) { didSomething = true; } } catch (RemoteException e) { Slog.w(TAG, "Exception in new application when starting activity " + hr.intent.getComponent().flattenToShortString(), e); throw e; } } } } } if (!didSomething) { ensureActivitiesVisibleLocked(null, 0); } return didSomething; }看到没有,这里仍然调用了realStartActivityLocked。再反复一下:
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { r.startFreezingScreenLocked(app, 0); if (false) Slog.d(TAG, "realStartActivity: setting app visibility true"); //setAppVisibility(true/false), 其作 用 是 告 诉WMS指定的窗体能否够被显示,这里为true。表示能够被显示 mWindowManager.setAppVisibility(r.appToken, true); //... try { //... app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP); //调用ApplicationThread.scheduleLaunchActivity app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo); if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) { //... } } catch (RemoteException e) { if (r.launchFailed) { // This is the second time we failed -- finish activity // and give up. Slog.e(TAG, "Second failure launching " + r.intent.getComponent().flattenToShortString() + ", giving up", e); mService.appDiedLocked(app); stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null, "2nd-crash", false); return false; } // This is the first time we failed -- restart process and // retry. app.activities.remove(r); throw e; } //... // Launch the new version setup screen if needed. We do this -after- // launching the initial activity (that is, home), so that it can have // a chance to initialize itself while in the background, making the // switch back to it faster and look better. if (isFrontStack(stack)) { mService.startSetupActivityLocked(); } // Update any services we are bound to that might care about whether // their client may have activities. mService.mServices.updateServiceConnectionActivitiesLocked(r.app); return true; }setAppVisibility(true/false), 其作 用是告诉WMS指定的窗体能否够被显示,这里为true,表示能够被显示。
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, 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; updatePendingConfiguration(curConfig); sendMessage(H.LAUNCH_ACTIVITY, r); }说明:scheduleLaunchActivity()方 法依据參数构造出一个本地ActivityRecord数据类 ,ActivityThread内部会为每个Activity创 建 一 个 ActivityRecord对象,并使用这些数据对象来管理Activity。
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); mSomeActivitiesChanged = true; if (r.profilerInfo != null) { mProfiler.setProfiler(r.profilerInfo); mProfiler.startProfiling(); } // Make sure we are running with the most recent config. handleConfigurationChanged(null, null); if (localLOGV) Slog.v( TAG, "Handling launch of " + r); // Initialize before creating the activity WindowManagerGlobal.initialize(); //得到一个Activity实例,在里面会运行onCreate方法 Activity a = performLaunchActivity(r, customIntent); if (a != null) { r.createdConfig = new Configuration(mConfiguration); Bundle oldState = r.state; // 调用目标activity的onResume,追踪源代码会发现 目标activity的onStart在里面会先于onResume调用 handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed); if (!r.activity.mFinished && r.startsNotResumed) { // The activity manager actually wants this one to start out // paused, because it needs to be visible but isn't in the // foreground. We accomplish this by going through the // normal startup (because activities expect to go through // onResume() the first time they run, before their window // is displayed), and then pausing it. However, in this case // we do -not- need to do the full pause cycle (of freezing // and such) because the activity manager assumes it can just // retain the current state it has. try { r.activity.mCalled = false; //这里再次去居然再次调用了callActivityOnPause?事实上在前面的performPauseActivity方法中已经调用了此方法,Activity_A已经运行了OnPause mInstrumentation.callActivityOnPause(r.activity); // We need to keep around the original state, in case // we need to be created again. But we only do this // for pre-Honeycomb apps, which always save their state // when pausing, so we can not have them save their state // when restarting from a paused state. For HC and later, // we want to (and can) let the state be saved as the normal // part of stopping the activity. if (r.isPreHoneycomb()) { r.state = oldState; } if (!r.activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onPause()"); } } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { if (!mInstrumentation.onException(r.activity, e)) { throw new RuntimeException( "Unable to pause activity " + r.intent.getComponent().toShortString() + ": " + e.toString(), e); } } r.paused = true; } } else { // If there was an error, for any reason, tell the activity // manager to stop us. try { ActivityManagerNative.getDefault() .finishActivity(r.token, Activity.RESULT_CANCELED, null, false); } catch (RemoteException ex) { // Ignore } } }继续追踪performLaunchActivity
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")"); //... Activity activity = null; try { java.lang.ClassLoader cl = r.packageInfo.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); } } try { Application app = r.packageInfo.makeApplication(false, mInstrumentation); //... if (activity != null) { //... //在这里最终開始调用目标Activity的OnCreate方法了 if (r.isPersistable()) { mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } //... if (!r.activity.mFinished) { //这里调用Activity_B的nRestoreInstanceState方法,获取保存在Bundle中的信息 if (r.isPersistable()) { if (r.state != null || r.persistentState != null) { mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, r.persistentState); } } else if (r.state != null) { mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state); } } //... } //... } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { //... } return activity; }Instrumentation.callActivityOnCreate会调用activity.performCreate(icicle, persistentState),activity.performCreate又会其调用onCreate方法(不贴代码了)。
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); mSomeActivitiesChanged = true; // TODO Push resumeArgs into the activity for consideration //在performResumeActivity里面调用了目标Activity_B的 onStart和onResume()方法。后面会追踪源代码 ActivityClientRecord r = performResumeActivity(token, clearHide); if (r != null) { final Activity a = r.activity; //... if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) { //... if (r.activity.mVisibleFromClient) { //过r.activity.makeVisible()调用目标Activity_B的 makeVisible()函数,该函数其内部又会辗转和WmS进行各种调用,并终于导致Activity包括 的DecorView显示到屏幕上 r.activity.makeVisible(); } } if (!r.onlyLocalRequest) { r.nextIdle = mNewActivities; mNewActivities = r; if (localLOGV) Slog.v( TAG, "Scheduling idle handler for " + r); //创建一个Idler对象,并加入到线程消息队列中, Looper.myQueue().addIdleHandler(new Idler()); } //... } else { //... } }
public final ActivityClientRecord performResumeActivity(IBinder token, boolean clearHide) { ActivityClientRecord r = mActivities.get(token); if (localLOGV) Slog.v(TAG, "Performing resume of " + r + " finished=" + r.activity.mFinished); if (r != null && !r.activity.mFinished) { if (clearHide) { r.hideForNow = false; r.activity.mStartedActivity = false; } try { //... r.activity.performResume(); //... } catch (Exception e) { //... } } return r; }
final void performResume() { //目标Activity的OnRestart和Onstart都在里面 performRestart(); mFragments.execPendingActions(); mLastNonConfigurationInstances = null; mCalled = false; // mResumed is set by the instrumentation // 调用了目标Activity的 onOnResume方法 mInstrumentation.callActivityOnResume(this); if (!mCalled) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onResume()"); } // Now really resume, and install the current status bar and menu. mCalled = false; mFragments.dispatchResume(); mFragments.execPendingActions(); onPostResume(); if (!mCalled) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onPostResume()"); } }还是得继续看performRestart
final void performRestart() { mFragments.noteStateNotSaved(); if (mStopped) { mStopped = false; if (mToken != null && mParent == null) { WindowManagerGlobal.getInstance().setStoppedState(mToken, false); } //... mCalled = false; //这里调用OnRestart方法 mInstrumentation.callActivityOnRestart(this); if (!mCalled) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onRestart()"); } //目标Activity的onStart在这里面 performStart(); } }
final void performStart() { //... // 目标Activity的onStart在这里运行 mInstrumentation.callActivityOnStart(this); if (!mCalled) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onStart()"); } //... }
public void callActivityOnStart(Activity activity) { activity.onStart(); }看到了activity.onStart()
public void callActivityOnResume(Activity activity) { activity.mResumed = true; activity.onResume(); if (mActivityMonitors != null) { synchronized (mSync) { final int N = mActivityMonitors.size(); for (int i=0; i<N; i++) { final ActivityMonitor am = mActivityMonitors.get(i); am.match(activity, activity, activity.getIntent()); } } } }
final void stopActivityLocked(ActivityRecord r) { //... if (r.app != null && r.app.thread != null) { adjustFocusedActivityLocked(r, "stopActivity"); r.resumeKeyDispatchingLocked(); try { //... //这里调用setAppVisibility(r.appToken, false)隐藏Activity_A if (!r.visible) { mWindowManager.setAppVisibility(r.appToken, false); } //这里则是调用ActivityThread.scheduleStopActivity r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags); //... Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r); mHandler.sendMessageDelayed(msg, STOP_TIMEOUT); } catch (Exception e) { //... } } }又回到了ActivityThread
public final void scheduleStopActivity(IBinder token, boolean showWindow, int configChanges) { sendMessage( showWindow ?告知H,运行 handleStopActivity,又会调用ActivityThread的performStopActivityInner,接着运行r.activity.performStop()调用Activity的performStopH.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE, token, 0, configChanges); }
final void performStop() { mDoReportFullyDrawn = false; //... if (!mStopped) { //... //这里Activity_A的OnStop方法 mInstrumentation.callActivityOnStop(this); if (!mCalled) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onStop()"); } //... mStopped = true; } mResumed = false; }Instrumentation.class
public void callActivityOnStop(Activity activity) { activity.onStop(); }最后调用了activity.onStop()
Activity生命周期的回调,你应该知道得很多其它!--Android源代码剖析(下)
标签:ash dstat nothing indent 代码 multi sdk 显示 second
原文地址:http://www.cnblogs.com/llguanli/p/7204921.html