Activity生命週期的回調,你應該知道得更多!--Android源碼剖析(下)

        接着上一篇繼續去追蹤Activity_B生命週期回調源碼。java

        繼續分析,在performPauseActivity方法中,回調了Activity的兩個操做函數:
        一 個是用於保存狀態的onSaveInstanceState(),另外一個就是onPause()  ,這裏你應該瞭解onPause和onSaveInstanceState的調用順序了,這裏看來OnSaveInstanceState是先於onPause的調用的,可是打印的Log顯示onSaveInstanceState在onPause以後,在onStop以前調用(不明白)。android

 

 

        最後r.state置爲true。app

        當 AmS通知當前Activity暫停後,AmS會當即返回,而在目標進程中則是發送一個暫停的消息,處理完該暫停消息後,目標進程會調用AmS的 activityPaused(),報 告 AMS本身已經暫停完畢,而後執行ActivityManagerNative.getDefault().activityPaused(token)
從而AMS將開始啓動真正的Activity。異步

        前面說過,ActivityManagerNative.getDefault().activityPaused的動做執行者是ActivityManagerService.activityPaused
        ActivityManagerService.classide

[java] view plain copy函數

  1. public final void activityPaused(IBinder token) {  
  2.     final long origId = Binder.clearCallingIdentity();  
  3.     synchronized(this) {  
  4.         ActivityStack stack = ActivityRecord.getStackLocked(token);  
  5.         if (stack != null) {  
  6.             stack.activityPausedLocked(token, false);  
  7.         }  
  8.     }  
  9.     Binder.restoreCallingIdentity(origId);  
  10. }  

        ActivityStack.class
[java] view plain copyoop

  1. final void activityPausedLocked(IBinder token, boolean timeout) {  
  2.        if (DEBUG_PAUSE) Slog.v(  
  3.            TAG, "Activity paused: token=" + token + ", timeout=" + timeout);  
  4.   
  5.        final ActivityRecord r = isInStackLocked(token);  
  6.        if (r != null) {  
  7.            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);  
  8.            if (mPausingActivity == r) {  
  9.                if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r  
  10.                        + (timeout ? " (due to timeout)" : " (pause complete)"));  
  11.                completePauseLocked(true);  
  12.            } else {  
  13.                EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,  
  14.                        r.userId, System.identityHashCode(r), r.shortComponentName,  
  15.                        mPausingActivity != null  
  16.                            ? mPausingActivity.shortComponentName : "(none)");  
  17.            }  
  18.        }  
  19.    }  

        ActivityStack.class
[java] view plain copy源碼分析

  1. private void completePauseLocked(boolean resumeNext) {  
  2.     ActivityRecord prev = mPausingActivity;  
  3.     if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev);  
  4.   
  5.     if (prev != null) {  
  6.         //...     
  7.     }  
  8.   
  9.     if (resumeNext) {  
  10.         final ActivityStack topStack = mStackSupervisor.getFocusedStack();  
  11.         if (!mService.isSleepingOrShuttingDown()) {  
  12.             mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);  
  13.         } else {  
  14.             mStackSupervisor.checkReadyForSleepLocked();  
  15.             ActivityRecord top = topStack.topRunningActivityLocked(null);  
  16.             if (top == null || (prev != null && top != prev)) {  
  17.                 // If there are no more activities available to run,  
  18.                 // do resume anyway to start something.  Also if the top  
  19.                 // activity on the stack is not the just paused activity,  
  20.                 // we need to go ahead and resume it to ensure we complete  
  21.                 // an in-flight app switch.  
  22.                 mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);  
  23.             }  
  24.         }  
  25.     }  
  26.   
  27.     if (prev != null) {  
  28.         //...  
  29.     }  
  30.   
  31.     // Notfiy when the task stack has changed  
  32.     mService.notifyTaskStackChangedLocked();  
  33. }  

        ActivityStackSupervisor.class
[java] view plain copyui

  1. boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,  
  2.                Bundle targetOptions) {  
  3.            if (targetStack == null) {  
  4.                targetStack = getFocusedStack();  
  5.            }  
  6.            // Do targetStack first.  
  7.            boolean result = false;  
  8.            if (isFrontStack(targetStack)) {  
  9.                result = targetStack.resumeTopActivityLocked(target, targetOptions);  
  10.            }  
  11.            for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {  
  12.                final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;  
  13.                for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {  
  14.                    final ActivityStack stack = stacks.get(stackNdx);  
  15.                    if (stack == targetStack) {  
  16.                        // Already started above.  
  17.                        continue;  
  18.                    }  
  19.                    if (isFrontStack(stack)) {  
  20.                   //調用 ActivityStack.resumeTopActivityLocked(null)方法正式啓動目標Activity  
  21.                        stack.resumeTopActivityLocked(null);  
  22.                    }  
  23.                }  
  24.            }  
  25.            return result;  
  26.        }    

        ActivityStack.classthis

[java] view plain copy

  1. final boolean resumeTopActivityLocked(ActivityRecord prev) {  
  2.        return resumeTopActivityLocked(prev, null);  
  3.    }  
  4.   
  5.    final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {  
  6.        if (mStackSupervisor.inResumeTopActivity) {  
  7.            // Don't even start recursing.  
  8.            return false;  
  9.        }  
  10.   
  11.        boolean result = false;  
  12.        try {  
  13.            // Protect against recursion.  
  14.            mStackSupervisor.inResumeTopActivity = true;  
  15.            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {  
  16.                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;  
  17.                mService.updateSleepIfNeededLocked();  
  18.            }  
  19.            result = resumeTopActivityInnerLocked(prev, options);  
  20.        } finally {  
  21.            mStackSupervisor.inResumeTopActivity = false;  
  22.        }  
  23.        return result;  
  24.    }  

        ActivityStack.class

[java] view plain copy

  1. final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {  
  2.     if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");  
  3.     //...  
  4.     if (next == null) {  
  5.         //...  
  6.     }  
  7.   
  8.     // If the top activity is the resumed one, nothing to do.  
  9.     if (mResumedActivity == next && next.state == ActivityState.RESUMED &&  
  10.                 mStackSupervisor.allResumedActivitiesComplete()) {  
  11.         //...  
  12.     }  
  13.   
  14.     final TaskRecord nextTask = next.task;  
  15.     if (prevTask != null && prevTask.stack == this &&  
  16.             prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {  
  17.         //...  
  18.     }  
  19.   //...  
  20.     ActivityStack lastStack = mStackSupervisor.getLastStack();  
  21.     if (next.app != null && next.app.thread != null) {  
  22.         //...  
  23.   
  24.     } else {  
  25.         // Whoops, need to restart this activity!  
  26.         if (!next.hasBeenLaunched) {  
  27.             next.hasBeenLaunched = true;  
  28.         } else {  
  29.             //...  
  30.         }  
  31.         if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Restarting " + next);  
  32.         mStackSupervisor.startSpecificActivityLocked(next, true, true);  
  33.     }  
  34.   
  35.     if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();  
  36.     return true;  
  37. }   

        若是上面不能直接resume已有的Activity對象,那麼接下來就要判斷目標Activity對應的進程是否存在。
        ActivityStackSupervisor.class

[java] view plain copy

  1. void startSpecificActivityLocked(ActivityRecord r,  
  2.                boolean andResume, boolean checkConfig) {  
  3.            // Is this activity's application already running?  
  4.         ////獲取目標Activity對應的進程對象ProcessRecord app  
  5.            ProcessRecord app = mService.getProcessRecordLocked(r.processName,  
  6.                    r.info.applicationInfo.uid, true);  
  7.   
  8.            r.task.stack.setLaunchTime(r);  
  9.            //若是目標Activity所在的app進程已經開啓,好比說直接從Activity_A打開Activity_B  
  10.            if (app != null && app.thread != null) {  
  11.                try {  
  12.                    if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0  
  13.                            || !"android".equals(r.info.packageName)) {  
  14.                        // Don't add this if it is a platform component that is marked  
  15.                        // to run in multiple processes, because this is actually  
  16.                        // part of the framework so doesn't make sense to track as a  
  17.                        // separate apk in the process.  
  18.                        app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,  
  19.                                mService.mProcessStats);  
  20.                    }  
  21.                    realStartActivityLocked(r, app, andResume, checkConfig);  
  22.                    //注意:在這裏return了  
  23.                    return;  
  24.                } catch (RemoteException e) {  
  25.                    Slog.w(TAG, "Exception when starting activity "  
  26.                            + r.intent.getComponent().flattenToShortString(), e);  
  27.                }  
  28.   
  29.                // If a dead object exception was thrown -- fall through to  
  30.                // restart the application.  
  31.            }  
  32.          //若是目標Activity所在的app進程還未開啓,若是是從Launcher啓動一個新的APP,則會調用此句(不會執行上面的if)  
  33.            mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,  
  34.                    "activity", r.intent.getComponent(), false, false, true);  
  35.        }  

        Activity_A打開Activity_B會執行if (app != null && app.thread != null) 中的realStartActivityLocked(r, app, andResume, checkConfig),由於已經目標Activity對應的進程已經開啓了,其實啓動目標進程以後(mService.startProcessLocked),仍是會調用realStartActivityLocked,這裏也順便去看一看是怎麼啓動目標進程的。

        追蹤ActivityManagerService.startProcessLocked,發現它會一步一步調用其重載函數(不貼代碼了),最後調用關鍵的

Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                    app.info.dataDir, entryPointArgs);

        經過Process.start啓動一個新的應用進程,而且應用進程會從ActivityThread類 的 main()方法中開始執行,轉了一圈,又回到了ActivityThread(上面說過:ActivityThread,該類爲應用程序的主線程類,全部的APK程序都有且僅有一個ActivityThread類 ,程序的入口爲該類中的static main()函數)。

        ActivityThread.class

[java] view plain copy

  1.   public static void main(String[] args) {  
  2.       SamplingProfilerIntegration.start();  
  3.       Looper.prepareMainLooper();  
  4.       ActivityThread thread = new ActivityThread();  
  5.       thread.attach(false);  
  6. //...             
  7.  Looper.loop();  
  8. //...         
  9. }  

        調用prepareMainLooper()在 U I線程建立一個消息隊列(MessageQueue),Looper.loop()讓消息循環。

        H (Handler)和ApplicationThread則是在ActivityThread的初始化的時候建立的

[java] view plain copy

  1. final ApplicationThread mAppThread = new ApplicationThread();  
  2. final Looper mLooper = Looper.myLooper();  
  3. final H mH = new H();  

        前面說過,ApplicationThread它是一個Binder對象,負責接收遠程AmS的 IPC 調用,接收到調用後,則通 過Handler把消息發送到消息隊列,U I主線程會異步地從消息隊列中取出消息並執行相應操做,好比 start、 stop、pause 等 。

        跟蹤main方法中的thread.attach(false)

[java] view plain copy

  1. private void attach(boolean system) {  
  2.     sCurrentActivityThread = this;  
  3.     mSystemThread = system;  
  4.     if (!system) {  
  5.      //...  
  6.         try {  
  7.             mgr.attachApplication(mAppThread);  
  8.         } catch (RemoteException ex) {  
  9.             // Ignore  
  10.         }  
  11.         //...  
  12.     } else {  
  13.           //...  
  14.     }  
  15.   
  16.     //...  
  17.     ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {  
  18.           //...  
  19.     });  
  20. }  

        能夠看到,這裏 mgr.attachApplication(mAppThread)把ActivityThread初始化時建立的mAppThread做爲參數傳遞過去
        再耐心地繼續跟蹤:
        ActivityManagerService.class

[java] view plain copy

  1. @Override  
  2.   public final void attachApplication(IApplicationThread thread) {  
  3.       synchronized (this) {  
  4.           int callingPid = Binder.getCallingPid();  
  5.           final long origId = Binder.clearCallingIdentity();  
  6.           attachApplicationLocked(thread, callingPid);  
  7.           Binder.restoreCallingIdentity(origId);  
  8.       }  
  9.   }  

        ActivityManagerService.class

[java] view plain copy

  1. private final boolean attachApplicationLocked(IApplicationThread thread,  
  2.         int pid) {  
  3.   
  4.     // Find the application record that is being attached...  either via  
  5.     // the pid if we are running in multiple processes, or just pull the  
  6.     // next app record if we are emulating process with anonymous threads.  
  7.     ProcessRecord app;  
  8.     if (pid != MY_PID && pid >= 0) {  
  9.         synchronized (mPidsSelfLocked) {  
  10.             app = mPidsSelfLocked.get(pid);  
  11.         }  
  12.     } else {  
  13.         app = null;  
  14.     }  
  15.   
  16.     if (app == null) {  
  17.         //...  
  18.         return false;  
  19.     }  
  20.   
  21.      
  22.   
  23.   //...  
  24.   
  25.     if (localLOGV) Slog.v(  
  26.         TAG, "New app record " + app  
  27.         + " thread=" + thread.asBinder() + " pid=" + pid);  
  28.     try {  
  29.          //...  
  30.         //經過thread.bindApplication調用ActivityThread.handleBindApplication,Binder機制  
  31.         thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,  
  32.                 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,  
  33.                 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,  
  34.                 isRestrictedBackupMode || !normalMode, app.persistent,  
  35.                 new Configuration(mConfiguration), app.compat,  
  36.                 getCommonServicesLocked(app.isolated),  
  37.                 mCoreSettingsObserver.getCoreSettingsLocked());  
  38.         updateLruProcessLocked(app, false, null);  
  39.         app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();  
  40.     } catch (Exception e) {  
  41.         //...  
  42.         return false;  
  43.     }  
  44.     //...  
  45.     // See if the top visible activity is waiting to run in this process...  
  46.     if (normalMode) {  
  47.         try {  
  48.             if (mStackSupervisor.attachApplicationLocked(app)) {  
  49.                 didSomething = true;  
  50.             }  
  51.         } catch (Exception e) {  
  52.             Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);  
  53.             badApp = true;  
  54.         }  
  55.     }  
  56.     //...  
  57.     return true;  
  58. }  

        經過thread.bindApplication調用ActivityThread.handleBindApplication,Binder機制

        ActivityThread.class

[java] view plain copy

  1. private void handleBindApplication(AppBindData data) {  
  2.     mBoundApplication = data;  
  3.     mConfiguration = new Configuration(data.config);  
  4.     mCompatConfiguration = new Configuration(data.config);  
  5.   
  6.    //...  
  7.   
  8.     if (data.instrumentationName != null) {  
  9.         InstrumentationInfo ii = null;  
  10.         try {  
  11.             ii = appContext.getPackageManager().  
  12.                 getInstrumentationInfo(data.instrumentationName, 0);  
  13.         } catch (PackageManager.NameNotFoundException e) {  
  14.         }  
  15.         if (ii == null) {  
  16.             throw new RuntimeException(  
  17.                 "Unable to find instrumentation info for: "  
  18.                 + data.instrumentationName);  
  19.         }  
  20.   
  21.         mInstrumentationPackageName = ii.packageName;  
  22.         mInstrumentationAppDir = ii.sourceDir;  
  23.         mInstrumentationSplitAppDirs = ii.splitSourceDirs;  
  24.         mInstrumentationLibDir = ii.nativeLibraryDir;  
  25.         mInstrumentedAppDir = data.info.getAppDir();  
  26.         mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();  
  27.         mInstrumentedLibDir = data.info.getLibDir();  
  28.   
  29.         ApplicationInfo instrApp = new ApplicationInfo();  
  30.         instrApp.packageName = ii.packageName;  
  31.         instrApp.sourceDir = ii.sourceDir;  
  32.         instrApp.publicSourceDir = ii.publicSourceDir;  
  33.         instrApp.splitSourceDirs = ii.splitSourceDirs;  
  34.         instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs;  
  35.         instrApp.dataDir = ii.dataDir;  
  36.         instrApp.nativeLibraryDir = ii.nativeLibraryDir;  
  37.         LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,  
  38.                 appContext.getClassLoader(), false, true, false);  
  39.         ContextImpl instrContext = ContextImpl.createAppContext(this, pi);  
  40.   
  41.         try {  
  42.             java.lang.ClassLoader cl = instrContext.getClassLoader();  
  43.            //Instrumentation的初始化,一個應用程序中只有一個Instrumentation對象,每一個Activity內部都有一個該對象的引用,初始化完成以後,幫助管理Activity生命週期的回調。  
  44.             mInstrumentation = (Instrumentation)  
  45.                 cl.loadClass(data.instrumentationName.getClassName()).newInstance();  
  46.         } catch (Exception e) {  
  47.             throw new RuntimeException(  
  48.                 "Unable to instantiate instrumentation "  
  49.                 + data.instrumentationName + ": " + e.toString(), e);  
  50.         }  
  51.   
  52.         mInstrumentation.init(this, instrContext, appContext,  
  53.                new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,  
  54.                data.instrumentationUiAutomationConnection);  
  55.         //...  
  56.   
  57.     } else {  
  58.         mInstrumentation = new Instrumentation();  
  59.     }  
  60.   
  61.     if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {  
  62.         dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();  
  63.     }  
  64.   
  65.     // Allow disk access during application and provider setup. This could  
  66.     // block processing ordered broadcasts, but later processing would  
  67.     // probably end up doing the same disk access.  
  68.     final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();  
  69.     try {  
  70.          //...  
  71.   
  72.         // Do this after providers, since instrumentation tests generally start their  
  73.         // test thread at this point, and we don't want that racing.  
  74.         try {  
  75.            //App   
  76.             mInstrumentation.onCreate(data.instrumentationArgs);  
  77.         }  
  78.         catch (Exception e) {  
  79.             throw new RuntimeException(  
  80.                 "Exception thrown in onCreate() of "  
  81.                 + data.instrumentationName + ": " + e.toString(), e);  
  82.         }  
  83.   
  84.         try {  
  85.           //回調Application的onCreate方法  
  86.             mInstrumentation.callApplicationOnCreate(app);  
  87.         } catch (Exception e) {  
  88.             if (!mInstrumentation.onException(app, e)) {  
  89.                 throw new RuntimeException(  
  90.                     "Unable to create application " + app.getClass().getName()  
  91.                     + ": " + e.toString(), e);  
  92.             }  
  93.         }  
  94.     } finally {  
  95.         StrictMode.setThreadPolicy(savedPolicy);  
  96.     }  
  97. }  

        前面提到的Instrumentation就是在裏面初始化的,初始化完成以後,幫助管理Activity生命週期的回調。

        再接着分析ActivityManagerService.attachApplicationLocked方法中的mStackSupervisor.attachApplicationLocked(app)

[java] view plain copy

  1. boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {  
  2.     final String processName = app.processName;  
  3.     boolean didSomething = false;  
  4.     for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {  
  5.         ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;  
  6.         for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {  
  7.             final ActivityStack stack = stacks.get(stackNdx);  
  8.             if (!isFrontStack(stack)) {  
  9.                 continue;  
  10.             }  
  11.             ActivityRecord hr = stack.topRunningActivityLocked(null);  
  12.             if (hr != null) {  
  13.                 if (hr.app == null && app.uid == hr.info.applicationInfo.uid  
  14.                         && processName.equals(hr.processName)) {  
  15.                     try {  
  16.                         //調用了realStartActivityLocked  
  17.                         if (realStartActivityLocked(hr, app, true, true)) {  
  18.                             didSomething = true;  
  19.                         }  
  20.                     } catch (RemoteException e) {  
  21.                         Slog.w(TAG, "Exception in new application when starting activity "  
  22.                               + hr.intent.getComponent().flattenToShortString(), e);  
  23.                         throw e;  
  24.                     }  
  25.                 }  
  26.             }  
  27.         }  
  28.     }  
  29.     if (!didSomething) {  
  30.         ensureActivitiesVisibleLocked(null, 0);  
  31.     }  
  32.     return didSomething;  
  33. }  

        看到沒有,這裏仍然調用了realStartActivityLocked,再重複一下:
若是目標進程還處於活動狀態,因此只須要讓目標進程再建立一個指定Activity的對象並執行之便可,調用realStartActivityLocked,不然,若是目標進程還不存在,則須要首先啓動目標進程,最後仍是要調用realStartActivityLocked

        仍是得繼續追蹤ActivityStackSupervisor中的realStartActivityLocked

        ActivityStackSupervisor.class

[java] view plain copy

  1. final boolean realStartActivityLocked(ActivityRecord r,  
  2.         ProcessRecord app, boolean andResume, boolean checkConfig)  
  3.         throws RemoteException {  
  4.   
  5.     r.startFreezingScreenLocked(app, 0);  
  6.     if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");  
  7.     //setAppVisibility(true/false), 其做 用 是 告 訴WMS指定的窗口是否能夠被顯示,這裏爲true,表示能夠被顯示  
  8.     mWindowManager.setAppVisibility(r.appToken, true);  
  9.      //...            
  10.     try {                              
  11.        //...  
  12.         app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);  
  13.         //調用ApplicationThread.scheduleLaunchActivity  
  14.         app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,  
  15.                 System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),  
  16.                 r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState,  
  17.                 r.icicle, r.persistentState, results, newIntents, !andResume,  
  18.                 mService.isNextTransitionForward(), profilerInfo);  
  19.   
  20.         if ((app.info.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {  
  21.             //...  
  22.         }  
  23.   
  24.     } catch (RemoteException e) {  
  25.         if (r.launchFailed) {  
  26.             // This is the second time we failed -- finish activity  
  27.             // and give up.  
  28.             Slog.e(TAG, "Second failure launching "  
  29.                   + r.intent.getComponent().flattenToShortString()  
  30.                   + ", giving up", e);  
  31.             mService.appDiedLocked(app);  
  32.             stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,  
  33.                     "2nd-crash", false);  
  34.             return false;  
  35.         }  
  36.   
  37.         // This is the first time we failed -- restart process and  
  38.         // retry.  
  39.         app.activities.remove(r);  
  40.         throw e;  
  41.     }  
  42.   
  43.   //...  
  44.   
  45.     // Launch the new version setup screen if needed.  We do this -after-  
  46.     // launching the initial activity (that is, home), so that it can have  
  47.     // a chance to initialize itself while in the background, making the  
  48.     // switch back to it faster and look better.  
  49.     if (isFrontStack(stack)) {  
  50.         mService.startSetupActivityLocked();  
  51.     }  
  52.   
  53.     // Update any services we are bound to that might care about whether  
  54.     // their client may have activities.  
  55.     mService.mServices.updateServiceConnectionActivitiesLocked(r.app);  
  56.   
  57.     return true;  
  58. }    

        setAppVisibility(true/false), 其做 用是告訴WMS指定的窗口是否能夠被顯示,這裏爲true,表示能夠被顯示。

        繼續追蹤ApplicationThread.scheduleLaunchActivity,還記得前面調用過ApplicationThread.schedulePauseActivity吧!

        ApplicationThread.class

[java] view plain copy

  1. public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,  
  2.         ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,  
  3.         String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,  
  4.         PersistableBundle persistentState, List<ResultInfo> pendingResults,  
  5.         List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward,  
  6.         ProfilerInfo profilerInfo) {  
  7.   
  8.     updateProcessState(procState, false);  
  9.   
  10.     ActivityClientRecord r = new ActivityClientRecord();  
  11.   
  12.     r.token = token;  
  13.     r.ident = ident;  
  14.     r.intent = intent;  
  15.     r.referrer = referrer;  
  16.     r.voiceInteractor = voiceInteractor;  
  17.     r.activityInfo = info;  
  18.     r.compatInfo = compatInfo;  
  19.     r.state = state;  
  20.     r.persistentState = persistentState;  
  21.   
  22.     r.pendingResults = pendingResults;  
  23.     r.pendingIntents = pendingNewIntents;  
  24.   
  25.     r.startsNotResumed = notResumed;  
  26.     r.isForward = isForward;  
  27.   
  28.     r.profilerInfo = profilerInfo;  
  29.   
  30.     updatePendingConfiguration(curConfig);  
  31.   
  32.     sendMessage(H.LAUNCH_ACTIVITY, r);  
  33. }  

        說明:scheduleLaunchActivity()方 法根據參數構造出一個本地ActivityRecord數據類 ,ActivityThread內部會爲每個Activity創 建 一 個 ActivityRecord對象,並使用這些數據對象來管理Activity。
        最後經過 sendMessage(H.LAUNCH_ACTIVITY, r)去掉用handleLaunchActivity(),在handleLaunchActivity裏面再調用到 performLaunchActivity()和 handleResumeActivity()
        H類前面已經解釋過了,再來看看 handleLaunchActivity

        ActivityThread.class

[java] view plain copy

  1. private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {  
  2.     // If we are getting ready to gc after going to the background, well  
  3.     // we are back active so skip it.  
  4.     unscheduleGcIdler();  
  5.     mSomeActivitiesChanged = true;  
  6.   
  7.     if (r.profilerInfo != null) {  
  8.         mProfiler.setProfiler(r.profilerInfo);  
  9.         mProfiler.startProfiling();  
  10.     }  
  11.   
  12.     // Make sure we are running with the most recent config.  
  13.     handleConfigurationChanged(null, null);  
  14.   
  15.     if (localLOGV) Slog.v(  
  16.         TAG, "Handling launch of " + r);  
  17.   
  18.     // Initialize before creating the activity  
  19.     WindowManagerGlobal.initialize();  
  20.    //獲得一個Activity實例,在裏面會執行onCreate方法  
  21.     Activity a = performLaunchActivity(r, customIntent);  
  22.   
  23.     if (a != null) {  
  24.         r.createdConfig = new Configuration(mConfiguration);  
  25.         Bundle oldState = r.state;  
  26.         // 調用目標activity的onResume,追蹤源碼會發現 目標activity的onStart在裏面會先於onResume調用            
  27.         handleResumeActivity(r.token, false, r.isForward,  
  28.                 !r.activity.mFinished && !r.startsNotResumed);  
  29.   
  30.         if (!r.activity.mFinished && r.startsNotResumed) {  
  31.             // The activity manager actually wants this one to start out  
  32.             // paused, because it needs to be visible but isn't in the  
  33.             // foreground.  We accomplish this by going through the  
  34.             // normal startup (because activities expect to go through  
  35.             // onResume() the first time they run, before their window  
  36.             // is displayed), and then pausing it.  However, in this case  
  37.             // we do -not- need to do the full pause cycle (of freezing  
  38.             // and such) because the activity manager assumes it can just  
  39.             // retain the current state it has.  
  40.             try {  
  41.                 r.activity.mCalled = false;  
  42.                 //這裏再次去居然再次調用了callActivityOnPause?其實在前面的performPauseActivity方法中已經調用了此方法,Activity_A已經執行了OnPause  
  43.                 mInstrumentation.callActivityOnPause(r.activity);  
  44.                 // We need to keep around the original state, in case  
  45.                 // we need to be created again.  But we only do this  
  46.                 // for pre-Honeycomb apps, which always save their state  
  47.                 // when pausing, so we can not have them save their state  
  48.                 // when restarting from a paused state.  For HC and later,  
  49.                 // we want to (and can) let the state be saved as the normal  
  50.                 // part of stopping the activity.  
  51.                 if (r.isPreHoneycomb()) {  
  52.                     r.state = oldState;  
  53.                 }  
  54.                 if (!r.activity.mCalled) {  
  55.                     throw new SuperNotCalledException(  
  56.                         "Activity " + r.intent.getComponent().toShortString() +  
  57.                         " did not call through to super.onPause()");  
  58.                 }  
  59.   
  60.             } catch (SuperNotCalledException e) {  
  61.                 throw e;  
  62.   
  63.             } catch (Exception e) {  
  64.                 if (!mInstrumentation.onException(r.activity, e)) {  
  65.                     throw new RuntimeException(  
  66.                             "Unable to pause activity "  
  67.                             + r.intent.getComponent().toShortString()  
  68.                             + ": " + e.toString(), e);  
  69.                 }  
  70.             }  
  71.             r.paused = true;  
  72.         }  
  73.     } else {  
  74.         // If there was an error, for any reason, tell the activity  
  75.         // manager to stop us.  
  76.         try {  
  77.             ActivityManagerNative.getDefault()  
  78.                 .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);  
  79.         } catch (RemoteException ex) {  
  80.             // Ignore  
  81.         }  
  82.     }  
  83. }  

        繼續追蹤performLaunchActivity

        ActivityThread.class

[java] view plain copy

  1. private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {  
  2.     // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");  
  3.     //...  
  4.     Activity activity = null;  
  5.     try {  
  6.         java.lang.ClassLoader cl = r.packageInfo.getClassLoader();  
  7.         activity = mInstrumentation.newActivity(  
  8.                 cl, component.getClassName(), r.intent);  
  9.         StrictMode.incrementExpectedActivityCount(activity.getClass());  
  10.         r.intent.setExtrasClassLoader(cl);  
  11.         r.intent.prepareToEnterProcess();  
  12.         if (r.state != null) {  
  13.             r.state.setClassLoader(cl);  
  14.         }  
  15.     } catch (Exception e) {  
  16.         if (!mInstrumentation.onException(activity, e)) {  
  17.             throw new RuntimeException(  
  18.                 "Unable to instantiate activity " + component  
  19.                 + ": " + e.toString(), e);  
  20.         }  
  21.     }  
  22.   
  23.     try {  
  24.         Application app = r.packageInfo.makeApplication(false, mInstrumentation);  
  25.          //...  
  26.         if (activity != null) {         
  27.              //...  
  28.              //在這裏終於開始調用目標Activity的OnCreate方法了  
  29.             if (r.isPersistable()) {  
  30.                 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);  
  31.             } else {  
  32.                 mInstrumentation.callActivityOnCreate(activity, r.state);  
  33.             }  
  34.             //...  
  35.             if (!r.activity.mFinished) {  
  36.                 //這裏調用Activity_B的nRestoreInstanceState方法,獲取保存在Bundle中的信息  
  37.                 if (r.isPersistable()) {  
  38.                     if (r.state != null || r.persistentState != null) {  
  39.                         mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,  
  40.                                 r.persistentState);  
  41.                     }  
  42.                 } else if (r.state != null) {  
  43.                     mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);  
  44.                 }  
  45.             }  
  46.           //...  
  47.         }  
  48.       //...  
  49.   
  50.     } catch (SuperNotCalledException e) {  
  51.         throw e;  
  52.   
  53.     } catch (Exception e) {  
  54.         //...  
  55.     }  
  56.   
  57.     return activity;  
  58. }  

        Instrumentation.callActivityOnCreate會調用activity.performCreate(icicle, persistentState),activity.performCreate又會其調用onCreate方法(不貼代碼了)。

        到這裏,Activity_B已經執行了onCreate方法,已經走完了Activity_A的onPause-->Activity_B的onCreate生命週期回調的流程。

        performLaunchActivity()方法返回後,執行ActivityThread.handleResumeActivity 

        ActivityThread.class

[java] view plain copy

  1. final void handleResumeActivity(IBinder token,  
  2.         boolean clearHide, boolean isForward, boolean reallyResume) {  
  3.     // If we are getting ready to gc after going to the background, well  
  4.     // we are back active so skip it.  
  5.     unscheduleGcIdler();  
  6.     mSomeActivitiesChanged = true;  
  7.   
  8.     // TODO Push resumeArgs into the activity for consideration  
  9.   //在performResumeActivity裏面調用了目標Activity_B的 onStart和onResume()方法,後面會追蹤源碼  
  10.     ActivityClientRecord r = performResumeActivity(token, clearHide);  
  11.   
  12.     if (r != null) {  
  13.         final Activity a = r.activity;  
  14.          //...  
  15.         
  16.         if (!r.activity.mFinished && willBeVisible  
  17.                 && r.activity.mDecor != null && !r.hideForNow) {  
  18.             //...  
  19.             if (r.activity.mVisibleFromClient) {  
  20.                //過r.activity.makeVisible()調用目標Activity_B的 makeVisible()函數,該函數其內部又會展轉和WmS進行各類調用,並最終致使Activity包含 的DecorView顯示到屏幕上                       
  21.                 r.activity.makeVisible();  
  22.             }  
  23.         }  
  24.           
  25.         if (!r.onlyLocalRequest) {  
  26.             r.nextIdle = mNewActivities;  
  27.             mNewActivities = r;  
  28.             if (localLOGV) Slog.v(  
  29.                 TAG, "Scheduling idle handler for " + r);  
  30.            //建立一個Idler對象,並添加到線程消息隊列中,  
  31.             Looper.myQueue().addIdleHandler(new Idler());  
  32.         }  
  33.       //...  
  34.   
  35.     } else {  
  36.         //...  
  37.     }  
  38. }    

        追蹤performResumeActivity

        ActivityThread.class

[java] view plain copy

  1. public final ActivityClientRecord performResumeActivity(IBinder token,  
  2.         boolean clearHide) {  
  3.     ActivityClientRecord r = mActivities.get(token);  
  4.     if (localLOGV) Slog.v(TAG, "Performing resume of " + r  
  5.             + " finished=" + r.activity.mFinished);  
  6.     if (r != null && !r.activity.mFinished) {  
  7.         if (clearHide) {  
  8.             r.hideForNow = false;  
  9.             r.activity.mStartedActivity = false;  
  10.         }  
  11.         try {  
  12.             //...  
  13.             r.activity.performResume();  
  14.   
  15.           //...  
  16.         } catch (Exception e) {  
  17.             //...  
  18.         }  
  19.     }  
  20.     return r;  
  21. }  

        繼續看performResume 

        Activity.class

[java] view plain copy

  1. final void performResume() {  
  2.    //目標Activity的OnRestart和Onstart都在裏面  
  3.     performRestart();  
  4.   
  5.     mFragments.execPendingActions();  
  6.   
  7.     mLastNonConfigurationInstances = null;  
  8.   
  9.     mCalled = false;  
  10.     // mResumed is set by the instrumentation  
  11.     // 調用了目標Activity的 onOnResume方法  
  12.     mInstrumentation.callActivityOnResume(this);  
  13.     if (!mCalled) {  
  14.         throw new SuperNotCalledException(  
  15.             "Activity " + mComponent.toShortString() +  
  16.             " did not call through to super.onResume()");  
  17.     }  
  18.   
  19.     // Now really resume, and install the current status bar and menu.  
  20.     mCalled = false;  
  21.   
  22.     mFragments.dispatchResume();  
  23.     mFragments.execPendingActions();  
  24.   
  25.     onPostResume();  
  26.     if (!mCalled) {  
  27.         throw new SuperNotCalledException(  
  28.             "Activity " + mComponent.toShortString() +  
  29.             " did not call through to super.onPostResume()");  
  30.     }  
  31. }  

        仍是得繼續看performRestart
[java] view plain copy

  1. final void performRestart() {  
  2.     mFragments.noteStateNotSaved();  
  3.   
  4.     if (mStopped) {  
  5.         mStopped = false;  
  6.         if (mToken != null && mParent == null) {  
  7.             WindowManagerGlobal.getInstance().setStoppedState(mToken, false);  
  8.         }  
  9.   
  10.       //...  
  11.   
  12.         mCalled = false;  
  13.         //這裏調用OnRestart方法  
  14.         mInstrumentation.callActivityOnRestart(this);  
  15.         if (!mCalled) {  
  16.             throw new SuperNotCalledException(  
  17.                 "Activity " + mComponent.toShortString() +  
  18.                 " did not call through to super.onRestart()");  
  19.         }  
  20.         //目標Activity的onStart在這裏面  
  21.         performStart();  
  22.     }  
  23. }  


[java] view plain copy

  1. final void performStart() {  
  2.     //...  
  3.     // 目標Activity的onStart在這裏執行  
  4.     mInstrumentation.callActivityOnStart(this);  
  5.     if (!mCalled) {  
  6.         throw new SuperNotCalledException(  
  7.             "Activity " + mComponent.toShortString() +  
  8.             " did not call through to super.onStart()");  
  9.     }  
  10.     //...  
  11. }  

        Instrumentation.class

[java] view plain copy

  1. public void callActivityOnStart(Activity activity) {  
  2.       activity.onStart();  
  3.   }  

        看到了activity.onStart()[java] view plain copy

  1. public void callActivityOnResume(Activity activity) {  
  2.         activity.mResumed = true;  
  3.         activity.onResume();  
  4.           
  5.         if (mActivityMonitors != null) {  
  6.             synchronized (mSync) {  
  7.                 final int N = mActivityMonitors.size();  
  8.                 for (int i=0; i<N; i++) {  
  9.                     final ActivityMonitor am = mActivityMonitors.get(i);  
  10.                     am.match(activity, activity, activity.getIntent());  
  11.                 }  
  12.             }  
  13.         }  
  14.     }  

        看到了activity.onResume()

 

        至此,從已經走到了Activity_B生命週期的onResume方法。

        源碼分析已經完成了Activity_A.onPause()--Activity_B.onCreate()--Activity_B.onStart()--Activity_B.onResume(),期間還看到了Activity的onSaveInstanceState(),OnRestoreInstanceState(),OnRestart()方法。

        還有最後Activity_A的onStop方法沒有看到,繼續看源碼吧!

        回到ActivityThread的handleResumeActivity方法,裏面的r.activity.makeVisible()去調用目標Activity_B的 makeVisible()函數,該函數其內部又會展轉和WmS進行各類調用,並最終致使Activity包含 的DecorView顯示到屏幕上(有待研究)。

        handleResumeActivity方法中還有一句Looper.myQueue().addIdleHandler(new Idler()),建立一個Idler對象,並添加到線程消息隊列中,而 Idler類的內部處理函數則是調用WmS的 activityldle()方法在該函數的內部則會展轉調用到stopActivityLocked()方法。

        ActivityStack.class

[java] view plain copy

  1. final void stopActivityLocked(ActivityRecord r) {  
  2.      //...  
  3.     if (r.app != null && r.app.thread != null) {  
  4.         adjustFocusedActivityLocked(r, "stopActivity");  
  5.         r.resumeKeyDispatchingLocked();  
  6.         try {  
  7.             //...  
  8.             //這裏調用setAppVisibility(r.appToken, false)隱藏Activity_A  
  9.             if (!r.visible) {  
  10.                 mWindowManager.setAppVisibility(r.appToken, false);  
  11.             }  
  12.             //這裏則是調用ActivityThread.scheduleStopActivity  
  13.             r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);  
  14.            //...  
  15.             Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);  
  16.             mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);  
  17.         } catch (Exception e) {  
  18.             //...  
  19.         }  
  20.     }  
  21. }  

        又回到了ActivityThread 

        ActivityThread.class 
[java] view plain copy

  1. public final void scheduleStopActivity(IBinder token, boolean showWindow,  
  2.                int configChanges) {  
  3.           sendMessage(  
  4.                showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,  
  5.                token, 0, configChanges);  
  6.        }  

        告知H,執行 handleStopActivity,又會調用ActivityThread的performStopActivityInner,接着執行r.activity.performStop()調用Activity的performStop

        Activity.class

[java] view plain copy

  1. final void performStop() {  
  2.     mDoReportFullyDrawn = false;  
  3.     //...  
  4.   
  5.     if (!mStopped) {  
  6.         //...  
  7.         //這裏Activity_A的OnStop方法  
  8.         mInstrumentation.callActivityOnStop(this);  
  9.         if (!mCalled) {  
  10.             throw new SuperNotCalledException(  
  11.                 "Activity " + mComponent.toShortString() +  
  12.                 " did not call through to super.onStop()");  
  13.         }  
  14.   
  15.         //...  
  16.         mStopped = true;  
  17.     }  
  18.     mResumed = false;  
  19. }    

       Instrumentation.class

[java] view plain copy

  1. public void callActivityOnStop(Activity activity) {  
  2.     activity.onStop();  
  3. }  

        最後調用了activity.onStop()


        至此,從Activity_A到Activity_B,分別經歷的生命週期執行過程和順序 走通了!!!!

Activity_A.onPause()--Activity_B.onCreate()--Activity_B.onStart()--Activity_B.onResume()--Activity_A.onStop()。

相關文章
相關標籤/搜索