【Android原始碼】Activity是如何建立的,以及生命週期的呼叫

指間沙似流年發表於2017-12-23

我們在開發Android的過程中,都知道Activity呼叫的生命週期的第一個就是onCreate。而我們所學的Java中所講的一個類的建構函式是首先被呼叫的,但是我們又極少在Activity中涉及到建構函式,而是隻需要關注生命週期就可以了。

我們經常認為的app的啟動就是Activity的啟動,而實際上並不是這樣,對於一個app來說,真正的入口是ActivityThread:

public final class ActivityThread {
    public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        SamplingProfilerIntegration.start();

        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        EventLogger.setReporter(new EventLoggingReporter());

        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);

        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
}
複製程式碼

可以發現ActivityThread類是一個final類,表明這個類是不能被繼承的,一個app對應一個ActivityThread。當Zygote程式孵化一個新的app的時候,會執行ActivityThread的main方法。 main方法中則是執行了大量的初始化工作,比如主執行緒的Handler、Looper,並呼叫thread.attach(false)繫結到ActivityManagerService上,之後就開始不斷的讀取訊息佇列並分發。 我們在觀察attach方法,其中false表示非系統應用:

private void attach(boolean system) {
   sCurrentActivityThread = this;
   mSystemThread = system;
   if (!system) {
       ViewRootImpl.addFirstDrawHandler(new Runnable() {
           @Override
           public void run() {
               ensureJitEnabled();
           }
       });
       android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                               UserHandle.myUserId());
       RuntimeInit.setApplicationObject(mAppThread.asBinder());
       final IActivityManager mgr = ActivityManagerNative.getDefault();
       try {
           mgr.attachApplication(mAppThread);
       } catch (RemoteException ex) {
           throw ex.rethrowFromSystemServer();
       }
   } else {
   }
}
複製程式碼

這個方法中我們主要關注mgr.attachApplication(mAppThread)方法,可以發現將ActivityThread繫結到了ActivityManagerService中:

@Override
public final void attachApplication(IApplicationThread thread) {
   synchronized (this) {
       int callingPid = Binder.getCallingPid();
       final long origId = Binder.clearCallingIdentity();
       attachApplicationLocked(thread, callingPid);
       Binder.restoreCallingIdentity(origId);
   }
}
private final boolean attachApplicationLocked(IApplicationThread thread,
       int pid) {
  	// 將ApplicationThread繫結到ActivityManagerService
	thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());
                    
	// 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;
       }
   }  
}

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 (!isFocusedStack(stack)) {
               continue;
           }
           ActivityRecord hr = stack.topRunningActivityLocked();
           if (hr != null) {
               if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                       && processName.equals(hr.processName)) {
                   try {
                       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, !PRESERVE_WINDOWS);
   }
   return didSomething;
}
複製程式碼

通過註釋可以發現是通過mStackSupervisor.attachApplicationLocked(app)來找到當前程式的最頂上的可見Activity,之後通過方法內的realStartActivityLocked(hr, app, true, true)來處理真正啟動Activity的邏輯:

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
       boolean andResume, boolean checkConfig) throws RemoteException {
		
   if (andResume) {
	   // 凍結尚未啟動的Activity
       r.startFreezingScreenLocked(app, 0);
  		// 給WindowManager設定token,標識當前的App要在前臺顯示
       mWindowManager.setAppVisibility(r.appToken, true);
       // schedule launch ticks to collect information about slow apps.
       r.startLaunchTickingLocked();
   }

   // 檢查配置資訊
   if (checkConfig) {
       Configuration config = mWindowManager.updateOrientationFromAppTokens(
               mService.mConfiguration,
               r.mayFreezeScreenLocked(app) ? r.appToken : null);
       mService.updateConfigurationLocked(config, r, false);
   }
		// 設定引數
   r.app = app;
   app.waitingToKill = null;
   r.launchCount++;
   r.lastLaunchTime = SystemClock.uptimeMillis();

   int idx = app.activities.indexOf(r);
   if (idx < 0) {
       app.activities.add(r);
   }
   mService.updateLruProcessLocked(app, true, null);
   mService.updateOomAdjLocked();

   final TaskRecord task = r.task;
   final ActivityStack stack = task.stack;
   try {
       if (app.thread == null) {
           throw new RemoteException();
       }
       List<ResultInfo> results = null;
       List<ReferrerIntent> newIntents = null;
       if (andResume) {
           results = r.results;
           newIntents = r.newIntents;
       }
       // 如果是桌面,將其新增到Activity棧的底部
       if (r.isHomeActivity()) {
           // Home process is the root process of the task.
           mService.mHomeProcess = task.mActivities.get(0).app;
       }
       mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
                                 PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
       r.sleeping = false;
       r.forceNewConfig = false;
       mService.showUnsupportedZoomDialogIfNeededLocked(r);
       mService.showAskCompatModeDialogLocked(r);
       r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
       ProfilerInfo profilerInfo = null;
       if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
           if (mService.mProfileProc == null || mService.mProfileProc == app) {
               mService.mProfileProc = app;
               final String profileFile = mService.mProfileFile;
               if (profileFile != null) {
                   ParcelFileDescriptor profileFd = mService.mProfileFd;
                   if (profileFd != null) {
                       try {
                           profileFd = profileFd.dup();
                       } catch (IOException e) {
                           if (profileFd != null) {
                               try {
                                   profileFd.close();
                               } catch (IOException o) {
                               }
                               profileFd = null;
                           }
                       }
                   }

                   profilerInfo = new ProfilerInfo(profileFile, profileFd,
                           mService.mSamplingInterval, mService.mAutoStopProfiler);
               }
           }
       }

       if (andResume) {
           app.hasShownUi = true;
           app.pendingUiClean = true;
       }
       app.forceProcessStateUpTo(mService.mTopProcessState);

       // 當所有的引數配置好之後,就準備啟動Activity  
       app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
               System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
               new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
               task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
               newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

       if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
           if (app.processName.equals(app.info.packageName)) {
               if (mService.mHeavyWeightProcess != null
                       && mService.mHeavyWeightProcess != app) {
                   Slog.w(TAG, "Starting new heavy weight process " + app
                           + " when already running "
                           + mService.mHeavyWeightProcess);
               }
               mService.mHeavyWeightProcess = app;
               Message msg = mService.mHandler.obtainMessage(
                       ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);
               msg.obj = r;
               mService.mHandler.sendMessage(msg);
           }
       }

   } 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;
   }

   r.launchFailed = false;
   if (stack.updateLRUListLocked(r)) {
       Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list");
   }

   if (andResume) {
       // As part of the process of launching, ActivityThread also performs
       // a resume.
       stack.minimalResumeActivityLocked(r);
   } else {
       if (DEBUG_STATES) Slog.v(TAG_STATES,
               "Moving to PAUSED: " + r + " (starting in paused state)");
       r.state = PAUSED;
   }
   if (isFocusedStack(stack)) {
       mService.startSetupActivityLocked();
   }
   if (r.app != null) {
       mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
   }

   return true;
}
複製程式碼

realStartActivityLocked方法首先會配置啟動Activity的各種引數,之後再呼叫ApplicationThread的scheduleLaunchActivity方法準備啟動Activity:

public final class ActivityThread {
	private class ApplicationThread extends ApplicationThreadNative {
	   @Override
	   public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
	           ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
	           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;
	
	       r.overrideConfig = overrideConfig;
	       updatePendingConfiguration(curConfig);
	
	       sendMessage(H.LAUNCH_ACTIVITY, r);
	   }
	}
}	
複製程式碼

可以發現這個方法其實就是準備啟動的資訊,構造了ActivityClientRecord,並最終通過sendMessage(H.LAUNCH_ACTIVITY, r)傳送啟動訊息給訊息佇列,給ActivityThread內的繼承了Handler的子類H來處理。

private class H extends Handler {
	public void handleMessage(Message msg) {
	      case LAUNCH_ACTIVITY: {
	          final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
	
	          r.packageInfo = getPackageInfoNoCheck(
	                  r.activityInfo.applicationInfo, r.compatInfo);
	          handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
	      } break;
	}
}

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
   Activity a = performLaunchActivity(r, customIntent);
}
複製程式碼

最終呼叫performLaunchActivity來處理Activity的啟動流程:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
	// 獲取ActivityInfo
   ActivityInfo aInfo = r.activityInfo;
   // 獲取PackageInfo
   if (r.packageInfo == null) {
       r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
               Context.CONTEXT_INCLUDE_CODE);
   }
	// 獲取Intent傳遞的ComponentName
   ComponentName component = r.intent.getComponent();
   if (component == null) {
       component = r.intent.resolveActivity(
           mInitialApplication.getPackageManager());
       r.intent.setComponent(component);
   }

   if (r.activityInfo.targetActivity != null) {
       component = new ComponentName(r.activityInfo.packageName,
               r.activityInfo.targetActivity);
   }
	// 通過反射構造Activity
   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) {
   }

   try {
   		// 獲取Application
       Application app = r.packageInfo.makeApplication(false, mInstrumentation);

       if (activity != null) {
           Context appContext = createBaseContextForActivity(r, activity);
           // 將application、window、context繫結到Activity上
           activity.attach(appContext, this, getInstrumentation(), r.token,
                   r.ident, app, r.intent, r.activityInfo, title, r.parent,
                   r.embeddedID, r.lastNonConfigurationInstances, config,
                   r.referrer, r.voiceInteractor, window);

           if (customIntent != null) {
               activity.mIntent = customIntent;
           }
           r.lastNonConfigurationInstances = null;
           activity.mStartedActivity = false;
           int theme = r.activityInfo.getThemeResource();
           if (theme != 0) {
               activity.setTheme(theme);
           }

           activity.mCalled = false;
           // 呼叫oncreate方法
           if (r.isPersistable()) {
               mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
           } else {
               mInstrumentation.callActivityOnCreate(activity, r.state);
           }
       }
       r.paused = true;

       mActivities.put(r.token, r);

   } catch (Exception e) {
   }

   return activity;
}
複製程式碼

這個方法主要用來處理Activity的啟動邏輯:

  1. 獲取ActivityInfo、PackageInfo、intent的ComponentName、Context、Window
  2. 通過反射構造Activity
  3. 將上面構造的隨想繫結到Activity中
  4. 呼叫callActivityOnCreate方法
public void callActivityOnCreate(Activity activity, Bundle icicle) {
   prePerformCreate(activity);
   activity.performCreate(icicle);
   postPerformCreate(activity);
}

// Activity.java
final void performCreate(Bundle icicle) {
   restoreHasCurrentPermissionRequest(icicle);
   onCreate(icicle);
   mActivityTransitionState.readState(icicle);
   performCreateCommon();
}
複製程式碼

最終通過performCreate方法,我們看到了我們所熟悉的onCreate方法,這個時候就走到了我們的生命週期方法中。 當然其他的生命週期方法也可以通過類似的方式來找到呼叫邏輯。

相關文章