Android原始碼解析之ActivityThread,深入瞭解應用程式

amadan發表於2021-09-09
  • 在Android開發中,程式猿接觸最多的就是Activity,其中必須會使用到的一個方法就是Activity的onCreate()方法,但是這個方法並不是程式的入口呼叫函式,他只是Activity的生命週期函式呼叫的第一個方法,而真正的程式入口在ActivityThread類的main方法.

    • 我們看下ActivityThread的main做了那些邏輯處理


  1.    public static void main(String[] args) {

  2.        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

  3.        SamplingProfilerIntegration.start();

  4.        // CloseGuard defaults to true and can be quite spammy.  We

  5.        // disable it here, but selectively enable it later (via

  6.        // StrictMode) on debug builds, but using DropBox, not logs.

  7.        CloseGuard.setEnabled(false);

  8.        Environment.initForCurrentUser();

  9.        // Set the reporter for event logging in libcore

  10.        EventLogger.setReporter(new EventLoggingReporter());

  11.        // Make sure TrustedCertificateStore looks in the right place for CA certificates

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

  13.        TrustedCertificateStore.setDefaultUserDirectory(configDir);

  14.        Process.setArgV0("");

  15.         //1.主執行緒Looper

  16.        Looper.prepareMainLooper();

  17.         //2.例項化ActivityThread物件,並呼叫attach()方法

  18.        ActivityThread thread = new ActivityThread();

  19.        thread.attach(false);

  20.        if (sMainThreadHandler == null) {

  21.            sMainThreadHandler = thread.getHandler();

  22.        }

  23.        if (false) {

  24.            Looper.myLooper().setMessageLogging(new

  25.                    LogPrinter(Log.DEBUG, "ActivityThread"));

  26.        }

  27.        // End of event ActivityThreadMain.

  28.        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

  29.         //3.開啟主執行緒Loooper輪詢

  30.        Looper.loop();

  31.        throw new RuntimeException("Main thread loop unexpectedly exited");

  32.    }

接著看thread.attach()方法的實現


  1.    private void attach(boolean system) {

  2.        sCurrentActivityThread = this;

  3.        mSystemThread = system;

  4.     

  5.         //system為false代表不是系統應用

  6.        if (!system) {

  7.            ViewRootImpl.addFirstDrawHandler(new Runnable() {

  8.                @Override

  9.                public void run() {

  10.                    ensureJitEnabled();

  11.                }

  12.            });

  13.            android.ddm.DdmHandleAppName.setAppName("",

  14.                                                    UserHandle.myUserId());

  15.            RuntimeInit.setApplicationObject(mAppThread.asBinder());

  16.     

  17.             //這個方法我們在上一篇部落格中講到過獲取的AMS物件,然後呼叫了AMS的attachApplication()方法

  18.            final IActivityManager mgr = ActivityManagerNative.getDefault();

  19.            try {

  20.                mgr.attachApplication(mAppThread);

  21.            } catch (RemoteException ex) {

  22.                throw ex.rethrowFromSystemServer();

  23.            }

  24.            // Watch for getting close to heap limit.

  25.            BinderInternal.addGcWatcher(new Runnable() {

  26.                @Override public void run() {

  27.                    if (!mSomeActivitiesChanged) {

  28.                        return;

  29.                    }

  30.                    Runtime runtime = Runtime.getRuntime();

  31.                    long dalvikMax = runtime.maxMemory();

  32.                    long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();

  33.                    if (dalvikUsed > ((3*dalvikMax)/4)) {

  34.                        if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)

  35.                                + " total=" + (runtime.totalMemory()/1024)

  36.                                + " used=" + (dalvikUsed/1024));

  37.                        mSomeActivitiesChanged = false;

  38.                        try {

  39.                            mgr.releaseSomeActivities(mAppThread);

  40.                        } catch (RemoteException e) {

  41.                            throw e.rethrowFromSystemServer();

  42.                        }

  43.                    }

  44.                }

  45.            });

  46.        } else {

  47.            // Don't set application object here -- if the system crashes,

  48.            // we can't display an alert, we just want to die die die.

  49.            android.ddm.DdmHandleAppName.setAppName("system_process",

  50.                    UserHandle.myUserId());

  51.            try {

  52.                mInstrumentation = new Instrumentation();

  53.                ContextImpl context = ContextImpl.createAppContext(

  54.                        this, getSystemContext().mPackageInfo);

  55.                mInitialApplication = context.mPackageInfo.makeApplication(true, null);

  56.                mInitialApplication.onCreate();

  57.            } catch (Exception e) {

  58.                throw new RuntimeException(

  59.                        "Unable to instantiate Application():" + e.toString(), e);

  60.            }

  61.        }

  62.        // add dropbox logging to libcore

  63.        DropBox.setReporter(new DropBoxReporter());

  64.        ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {

  65.            @Override

  66.            public void onConfigurationChanged(Configuration newConfig) {

  67.                synchronized (mResourcesManager) {

  68.                    // We need to apply this change to the resources

  69.                    // immediately, because upon returning the view

  70.                    // hierarchy will be informed about it.

  71.                    if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) {

  72.                        updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),

  73.                                mResourcesManager.getConfiguration().getLocales());

  74.                        // This actually changed the resources!  Tell

  75.                        // everyone about it.

  76.                        if (mPendingConfiguration == null ||

  77.                                mPendingConfiguration.isOtherSeqNewer(newConfig)) {

  78.                            mPendingConfiguration = newConfig;

  79.                            sendMessage(H.CONFIGURATION_CHANGED, newConfig);

  80.                        }

  81.                    }

  82.                }

  83.            }

  84.            @Override

  85.            public void onLowMemory() {

  86.            }

  87.            @Override

  88.            public void onTrimMemory(int level) {

  89.            }

  90.        });

  91.    }

接著看AMS的attachApplication()方法-->呼叫的是attachApplicationLocked()



  1.    private final boolean attachApplicationLocked(IApplicationThread thread,

  2.            int pid) {

  3.        // Find the application record that is being attached...  either via

  4.        // the pid if we are running in multiple processes, or just pull the

  5.        // next app record if we are emulating process with anonymous threads.

  6.        ProcessRecord app;

  7.        if (pid != MY_PID && pid >= 0) {

  8.            synchronized (mPidsSelfLocked) {

  9.                app = mPidsSelfLocked.get(pid);

  10.            }

  11.        } else {

  12.            app = null;

  13.        }

  14.        if (app == null) {

  15.            Slog.w(TAG, "No pending application record for pid " + pid

  16.                    + " (IApplicationThread " + thread + "); dropping process");

  17.            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);

  18.            if (pid > 0 && pid != MY_PID) {

  19.                Process.killProcessQuiet(pid);

  20.                //TODO: killProcessGroup(app.info.uid, pid);

  21.            } else {

  22.                try {

  23.                    thread.scheduleExit();

  24.                } catch (Exception e) {

  25.                    // Ignore exceptions.

  26.                }

  27.            }

  28.            return false;

  29.        }

  30.        // If this application record is still attached to a previous

  31.        // process, clean it up now.

  32.        if (app.thread != null) {

  33.            handleAppDiedLocked(app, true, true);

  34.        }

  35.        // Tell the process all about itself.

  36.        if (DEBUG_ALL) Slog.v(

  37.                TAG, "Binding process pid " + pid + " to record " + app);

  38.        final String processName = app.processName;

  39.        try {

  40.            AppDeathRecipient adr = new AppDeathRecipient(

  41.                    app, pid, thread);

  42.            thread.asBinder().linkToDeath(adr, 0);

  43.            app.deathRecipient = adr;

  44.        } catch (RemoteException e) {

  45.            app.resetPackageList(mProcessStats);

  46.            startProcessLocked(app, "link fail", processName);

  47.            return false;

  48.        }

  49.        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);

  50.        app.makeActive(thread, mProcessStats);

  51.        app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;

  52.        app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;

  53.        app.forcingToForeground = null;

  54.        updateProcessForegroundLocked(app, false, false);

  55.        app.hasShownUi = false;

  56.        app.debugging = false;

  57.        app.cached = false;

  58.        app.killedByAm = false;

  59.        // We carefully use the same state that PackageManager uses for

  60.        // filtering, since we use this flag to decide if we need to install

  61.        // providers when user is unlocked later

  62.        app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);

  63.        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);

  64.        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);

  65.        List providers = normalMode ? generateApplicationProvidersLocked(app) : null;

  66.        if (providers != null && checkAppInLaunchingProvidersLocked(app)) {

  67.            Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);

  68.            msg.obj = app;

  69.            mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);

  70.        }

  71.        if (!normalMode) {

  72.            Slog.i(TAG, "Launching preboot mode app: " + app);

  73.        }

  74.        if (DEBUG_ALL) Slog.v(

  75.            TAG, "New app record " + app

  76.            + " thread=" + thread.asBinder() + " pid=" + pid);

  77.        try {

  78.            int testMode = IApplicationThread.DEBUG_OFF;

  79.            if (mDebugApp != null && mDebugApp.equals(processName)) {

  80.                testMode = mWaitForDebugger

  81.                    ? IApplicationThread.DEBUG_WAIT

  82.                    : IApplicationThread.DEBUG_ON;

  83.                app.debugging = true;

  84.                if (mDebugTransient) {

  85.                    mDebugApp = mOrigDebugApp;

  86.                    mWaitForDebugger = mOrigWaitForDebugger;

  87.                }

  88.            }

  89.            String profileFile = app.instrumentationProfileFile;

  90.            ParcelFileDescriptor profileFd = null;

  91.            int samplingInterval = 0;

  92.            boolean profileAutoStop = false;

  93.            if (mProfileApp != null && mProfileApp.equals(processName)) {

  94.                mProfileProc = app;

  95.                profileFile = mProfileFile;

  96.                profileFd = mProfileFd;

  97.                samplingInterval = mSamplingInterval;

  98.                profileAutoStop = mAutoStopProfiler;

  99.            }

  100.            boolean enableTrackAllocation = false;

  101.            if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {

  102.                enableTrackAllocation = true;

  103.                mTrackAllocationApp = null;

  104.            }

  105.            // If the app is being launched for restore or full backup, set it up specially

  106.            boolean isRestrictedBackupMode = false;

  107.            if (mBackupTarget != null && mBackupAppName.equals(processName)) {

  108.                isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID

  109.                        && ((mBackupTarget.backupMode == BackupRecord.RESTORE)

  110.                                || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)

  111.                                || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));

  112.            }

  113.            if (app.instrumentationClass != null) {

  114.                notifyPackageUse(app.instrumentationClass.getPackageName(),

  115.                                 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);

  116.            }

  117.            if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "

  118.                    + processName + " with config " + mConfiguration);

  119.            ApplicationInfo appInfo = app.instrumentationInfo != null

  120.                    ? app.instrumentationInfo : app.info;

  121.            app.compat = compatibilityInfoForPackageLocked(appInfo);

  122.            if (profileFd != null) {

  123.                profileFd = profileFd.dup();

  124.            }

  125.            ProfilerInfo profilerInfo = profileFile == null ? null

  126.                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);

  127.     

  128.             //1.這是個重要方法,根據名字就可以知道該方法的作用就是將ApplicationThread繫結到AMS上.

  129.            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,

  130.                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,

  131.                    app.instrumentationUiAutomationConnection, testMode,

  132.                    mBinderTransactionTrackingEnabled, enableTrackAllocation,

  133.                    isRestrictedBackupMode || !normalMode, app.persistent,

  134.                    new Configuration(mConfiguration), app.compat,

  135.                    getCommonServicesLocked(app.isolated),

  136.                    mCoreSettingsObserver.getCoreSettingsLocked());

  137.            updateLruProcessLocked(app, false, null);

  138.            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();

  139.        } catch (Exception e) {

  140.            // todo: Yikes!  What should we do?  For now we will try to

  141.            // start another process, but that could easily get us in

  142.            // an infinite loop of restarting processes...

  143.            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);

  144.            app.resetPackageList(mProcessStats);

  145.            app.unlinkDeathRecipient();

  146.            startProcessLocked(app, "bind fail", processName);

  147.            return false;

  148.        }

  149.        // Remove this record from the list of starting applications.

  150.        mPersistentStartingProcesses.remove(app);

  151.        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,

  152.                "Attach application locked removing on hold: " + app);

  153.        mProcessesOnHold.remove(app);

  154.        boolean badApp = false;

  155.        boolean didSomething = false;

  156.        // See if the top visible activity is waiting to run in this process...

  157.        if (normalMode) {

  158.            try {

  159.     

  160.                 //2.第二個重要方法就是呼叫了AcitvityStackSupervisor的attachApplicationLocked()方法

  161.                if (mStackSupervisor.attachApplicationLocked(app)) {

  162.                    didSomething = true;

  163.                }

  164.            } catch (Exception e) {

  165.                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);

  166.                badApp = true;

  167.            }

  168.        }

  169.        // Find any services that should be running in this process...

  170.        if (!badApp) {

  171.            try {

  172.                didSomething |= mServices.attachApplicationLocked(app, processName);

  173.            } catch (Exception e) {

  174.                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);

  175.                badApp = true;

  176.            }

  177.        }

  178.        // Check if a next-broadcast receiver is in this process...

  179.        if (!badApp && isPendingBroadcastProcessLocked(pid)) {

  180.            try {

  181.                didSomething |= sendPendingBroadcastsLocked(app);

  182.            } catch (Exception e) {

  183.                // If the app died trying to launch the receiver we declare it 'bad'

  184.                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);

  185.                badApp = true;

  186.            }

  187.        }

  188.        // Check whether the next backup agent is in this process...

  189.        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {

  190.            if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,

  191.                    "New app is backup target, launching agent for " + app);

  192.            notifyPackageUse(mBackupTarget.appInfo.packageName,

  193.                             PackageManager.NOTIFY_PACKAGE_USE_BACKUP);

  194.            try {

  195.                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,

  196.                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),

  197.                        mBackupTarget.backupMode);

  198.            } catch (Exception e) {

  199.                Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);

  200.                badApp = true;

  201.            }

  202.        }

  203.        if (badApp) {

  204.            app.kill("error during init", true);

  205.            handleAppDiedLocked(app, false, true);

  206.            return false;

  207.        }

  208.        if (!didSomething) {

  209.            updateOomAdjLocked();

  210.        }

  211.        return true;

  212.    }

  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的attachApplication()方法中接著呼叫了attachApplicationLocked()為繫結Application加鎖,接著呼叫了ApplicationThread的bindApplication()方法,將Application繫結到AMS上,最後呼叫的ActivityStackSupervisor的attachApplicationLocked()方法,我們接著看在該方法中處理了那些邏輯


  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 stacks = mActivityDisplays.valueAt(displayNdx).mStacks;

  6.            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {

  7.                final ActivityStack stack = stacks.get(stackNdx);

  8.                if (!isFocusedStack(stack)) {

  9.                    continue;

  10.                }

  11.                ActivityRecord hr = stack.topRunningActivityLocked();

  12.                if (hr != null) {

  13.                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid

  14.                            && processName.equals(hr.processName)) {

  15.                        try {

  16.                         //真正我們要看的方法就是這個方法

  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, !PRESERVE_WINDOWS);

  31.        }

  32.        return didSomething;

  33.    }

realStartActivityLocked()看方法名字也知道該方法的作用是真正啟動Activity的方法


  1.    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,

  2.            boolean andResume, boolean checkConfig) throws RemoteException {

  3.        if (!allPausedActivitiesComplete()) {

  4.            // While there are activities pausing we skipping starting any new activities until

  5.            // pauses are complete. NOTE: that we also do this for activities that are starting in

  6.            // the paused state because they will first be resumed then paused on the client side.

  7.            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,

  8.                    "realStartActivityLocked: Skipping start of r=" + r

  9.                    + " some activities pausing...");

  10.            return false;

  11.        }

  12.        if (andResume) {

  13.          //凍結未尚未啟動的其他activity

  14.            r.startFreezingScreenLocked(app, 0);

  15.          //標示當前app要位於前臺顯示

  16.            mWindowManager.setAppVisibility(r.appToken, true);

  17.            // 蒐集啟動較慢的app資訊

  18.            r.startLaunchTickingLocked();

  19.        }

  20.        // 檢查配置資訊

  21.        if (checkConfig) {

  22.            Configuration config = mWindowManager.updateOrientationFromAppTokens(

  23.                    mService.mConfiguration,

  24.                    r.mayFreezeScreenLocked(app) ? r.appToken : null);

  25.            // Deferring resume here because we're going to launch new activity shortly.

  26.            // We don't want to perform a redundant launch of the same record while ensuring

  27.            // configurations and trying to resume top activity of focused stack.

  28.            mService.updateConfigurationLocked(config, r, false, true );

  29.        }

  30.             //設定相關引數資訊

  31.        r.app = app;

  32.        app.waitingToKill = null;

  33.        r.launchCount++;

  34.        r.lastLaunchTime = SystemClock.uptimeMillis();

  35.        if (DEBUG_ALL) Slog.v(TAG, "Launching: " + r);

  36.        int idx = app.activities.indexOf(r);

  37.        if (idx

  38.            app.activities.add(r);

  39.        }

  40.        mService.updateLruProcessLocked(app, true, null);

  41.        mService.updateOomAdjLocked();

  42.        final TaskRecord task = r.task;

  43.        if (task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE ||

  44.                task.mLockTaskAuth == LOCK_TASK_AUTH_LAUNCHABLE_PRIV) {

  45.            setLockTaskModeLocked(task, LOCK_TASK_MODE_LOCKED, "mLockTaskAuth==LAUNCHABLE", false);

  46.        }

  47.        final ActivityStack stack = task.stack;

  48.        try {

  49.            if (app.thread == null) {

  50.                throw new RemoteException();

  51.            }

  52.            List results = null;

  53.            List newIntents = null;

  54.            if (andResume) {

  55.                results = r.results;

  56.                newIntents = r.newIntents;

  57.            }

  58.            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,

  59.                    "Launching: " + r + " icicle=" + r.icicle + " with results=" + results

  60.                    + " newIntents=" + newIntents + " andResume=" + andResume);

  61.            if (andResume) {

  62.                EventLog.writeEvent(EventLogTags.AM_RESTART_ACTIVITY,

  63.                        r.userId, System.identityHashCode(r),

  64.                        task.taskId, r.shortComponentName);

  65.            }

  66.            if (r.isHomeActivity()) {

  67.                // 是否是桌面activity,是的話將其新增到棧底

  68.                mService.mHomeProcess = task.mActivities.get(0).app;

  69.            }

  70.            mService.notifyPackageUse(r.intent.getComponent().getPackageName(),

  71.                                      PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);

  72.            r.sleeping = false;

  73.            r.forceNewConfig = false;

  74.            mService.showUnsupportedZoomDialogIfNeededLocked(r);

  75.            mService.showAskCompatModeDialogLocked(r);

  76.            r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);

  77.            ProfilerInfo profilerInfo = null;

  78.            if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {

  79.                if (mService.mProfileProc == null || mService.mProfileProc == app) {

  80.                    mService.mProfileProc = app;

  81.                    final String profileFile = mService.mProfileFile;

  82.                    if (profileFile != null) {

  83.                        ParcelFileDescriptor profileFd = mService.mProfileFd;

  84.                        if (profileFd != null) {

  85.                            try {

  86.                                profileFd = profileFd.dup();

  87.                            } catch (IOException e) {

  88.                                if (profileFd != null) {

  89.                                    try {

  90.                                        profileFd.close();

  91.                                    } catch (IOException o) {

  92.                                    }

  93.                                    profileFd = null;

  94.                                }

  95.                            }

  96.                        }

  97.                        profilerInfo = new ProfilerInfo(profileFile, profileFd,

  98.                                mService.mSamplingInterval, mService.mAutoStopProfiler);

  99.                    }

  100.                }

  101.            }

  102.            if (andResume) {

  103.                app.hasShownUi = true;

  104.                app.pendingUiClean = true;

  105.            }

  106.            app.forceProcessStateUpTo(mService.mTopProcessState);

  107.          //所有資訊準備完畢了,開始啟動activity

  108.            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,

  109.                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),

  110.                    new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,

  111.                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,

  112.                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

  113.            if ((app.info.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {

  114.                // This may be a heavy-weight process!  Note that the package

  115.                // manager will ensure that only activity can run in the main

  116.                // process of the .apk, which is the only thing that will be

  117.                // considered heavy-weight.

  118.                if (app.processName.equals(app.info.packageName)) {

  119.                    if (mService.mHeavyWeightProcess != null

  120.                            && mService.mHeavyWeightProcess != app) {

  121.                        Slog.w(TAG, "Starting new heavy weight process " + app

  122.                                + " when already running "

  123.                                + mService.mHeavyWeightProcess);

  124.                    }

  125.                    mService.mHeavyWeightProcess = app;

  126.                    Message msg = mService.mHandler.obtainMessage(

  127.                            ActivityManagerService.POST_HEAVY_NOTIFICATION_MSG);

  128.                    msg.obj = r;

  129.                    mService.mHandler.sendMessage(msg);

  130.                }

  131.            }

  132.        } catch (RemoteException e) {

  133.            if (r.launchFailed) {

  134.                // This is the second time we failed -- finish activity

  135.                // and give up.

  136.                Slog.e(TAG, "Second failure launching "

  137.                      + r.intent.getComponent().flattenToShortString()

  138.                      + ", giving up", e);

  139.                mService.appDiedLocked(app);

  140.                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,

  141.                        "2nd-crash", false);

  142.                return false;

  143.            }

  144.            // This is the first time we failed -- restart process and

  145.            // retry.

  146.            app.activities.remove(r);

  147.            throw e;

  148.        }

  149.        r.launchFailed = false;

  150.        if (stack.updateLRUListLocked(r)) {

  151.            Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list");

  152.        }

  153.        if (andResume) {

  154.            // As part of the process of launching, ActivityThread also performs

  155.            // a resume.

  156.            stack.minimalResumeActivityLocked(r);

  157.        } else {

  158.            // This activity is not starting in the resumed state... which should look like we asked

  159.            // it to pause+stop (but remain visible), and it has done so and reported back the

  160.            // current icicle and other state.

  161.            if (DEBUG_STATES) Slog.v(TAG_STATES,

  162.                    "Moving to PAUSED: " + r + " (starting in paused state)");

  163.            r.state = PAUSED;

  164.        }

  165.        // Launch the new version setup screen if needed.  We do this -after-

  166.        // launching the initial activity (that is, home), so that it can have

  167.        // a chance to initialize itself while in the background, making the

  168.        // switch back to it faster and look better.

  169.        if (isFocusedStack(stack)) {

  170.            mService.startSetupActivityLocked();

  171.        }

  172.        // Update any services we are bound to that might care about whether

  173.        // their client may have activities.

  174.        if (r.app != null) {

  175.            mService.mServices.updateServiceConnectionActivitiesLocked(r.app);

  176.        }

  177.        return true;

  178.    }

最後呼叫了ApplicationThread的scheduleLaunchActivity()


  1.        @Override

  2.        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,

  3.                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,

  4.                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,

  5.                int procState, Bundle state, PersistableBundle persistentState,

  6.                List pendingResults, List pendingNewIntents,

  7.                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

  8.            updateProcessState(procState, false);

  9.            ActivityClientRecord r = new ActivityClientRecord();

  10.            r.token = token;

  11.            r.ident = ident;

  12.            r.intent = intent;

  13.            r.referrer = referrer;

  14.            r.voiceInteractor = voiceInteractor;

  15.            r.activityInfo = info;

  16.            r.compatInfo = compatInfo;

  17.            r.state = state;

  18.            r.persistentState = persistentState;

  19.            r.pendingResults = pendingResults;

  20.            r.pendingIntents = pendingNewIntents;

  21.            r.startsNotResumed = notResumed;

  22.            r.isForward = isForward;

  23.            r.profilerInfo = profilerInfo;

  24.            r.overrideConfig = overrideConfig;

  25.            updatePendingConfiguration(curConfig);

  26.                     //所有資訊進行封裝後,透過handler傳送訊息的方式來啟動

  27.            sendMessage(H.LAUNCH_ACTIVITY, r);

  28.        }


  1.        public void handleMessage(Message msg) {

  2.            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));

  3.            switch (msg.what) {

  4.                case LAUNCH_ACTIVITY: {

  5.                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");

  6.                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

  7.                    r.packageInfo = getPackageInfoNoCheck(

  8.                            r.activityInfo.applicationInfo, r.compatInfo);

  9.                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");

  10.                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

  11.                } break;

Handler接收到訊息通知後,呼叫handleLaunchActivity()方法啟動activity


  1.   private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {

  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.        if (r.profilerInfo != null) {

  7.            mProfiler.setProfiler(r.profilerInfo);

  8.            mProfiler.startProfiling();

  9.        }

  10.        // Make sure we are running with the most recent config.

  11.        handleConfigurationChanged(null, null);

  12.        if (localLOGV) Slog.v(

  13.            TAG, "Handling launch of " + r);

  14.        // 在初始化activity前進行處理

  15.        WindowManagerGlobal.initialize();

  16.               //真正執行activity的方法

  17.         Activity a = performLaunchActivity(r, customIntent);

  18.        if (a != null) {

  19.            r.createdConfig = new Configuration(mConfiguration);

  20.            reportSizeConfigurations(r);

  21.            Bundle oldState = r.state;

  22.            handleResumeActivity(r.token, false, r.isForward,

  23.                    !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

  24.            if (!r.activity.mFinished && r.startsNotResumed) {

  25.                // The activity manager actually wants this one to start out paused, because it

  26.                // needs to be visible but isn't in the foreground. We accomplish this by going

  27.                // through the normal startup (because activities expect to go through onResume()

  28.                // the first time they run, before their window is displayed), and then pausing it.

  29.                // However, in this case we do -not- need to do the full pause cycle (of freezing

  30.                // and such) because the activity manager assumes it can just retain the current

  31.                // state it has.

  32.                performPauseActivityIfNeeded(r, reason);

  33.                // We need to keep around the original state, in case we need to be created again.

  34.                // But we only do this for pre-Honeycomb apps, which always save their state when

  35.                // pausing, so we can not have them save their state when restarting from a paused

  36.                // state. For HC and later, we want to (and can) let the state be saved as the

  37.                // normal part of stopping the activity.

  38.                if (r.isPreHoneycomb()) {

  39.                    r.state = oldState;

  40.                }

  41.            }

  42.        } else {

  43.            // If there was an error, for any reason, tell the activity manager to stop us.

  44.            try {

  45.                ActivityManagerNative.getDefault()

  46.                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,

  47.                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);

  48.            } catch (RemoteException ex) {

  49.                throw ex.rethrowFromSystemServer();

  50.            }

  51.        }

  52.    }

真正啟動activity的方法


  1.    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {    

  2.        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

  3.        ActivityInfo aInfo = r.activityInfo;

  4.        if (r.packageInfo == null) {

  5.            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,

  6.                    Context.CONTEXT_INCLUDE_CODE);

  7.        }

  8.             //拿到Component資訊

  9.         ComponentName component = r.intent.getComponent();

  10.        if (component == null) {

  11.            component = r.intent.resolveActivity(

  12.                mInitialApplication.getPackageManager());

  13.            r.intent.setComponent(component);

  14.        }

  15.        if (r.activityInfo.targetActivity != null) {

  16.            component = new ComponentName(r.activityInfo.packageName,

  17.                    r.activityInfo.targetActivity);

  18.        }

  19.        Activity activity = null;

  20.        try {

  21.         //透過反射方式例項化ClassLoader,然後再反射例項化activity

  22.            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();

  23.            activity = mInstrumentation.newActivity(

  24.                    cl, component.getClassName(), r.intent);

  25.            StrictMode.incrementExpectedActivityCount(activity.getClass());

  26.            r.intent.setExtrasClassLoader(cl);

  27.            r.intent.prepareToEnterProcess();

  28.            if (r.state != null) {

  29.                r.state.setClassLoader(cl);

  30.            }

  31.        } catch (Exception e) {

  32.            if (!mInstrumentation.onException(activity, e)) {

  33.                throw new RuntimeException(

  34.                    "Unable to instantiate activity " + component

  35.                    + ": " + e.toString(), e);

  36.            }

  37.        }

  38.        try {

  39.          //獲取Application物件

  40.            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

  41.            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);

  42.            if (localLOGV) Slog.v(

  43.                    TAG, r + ": app=" + app

  44.                    + ", appName=" + app.getPackageName()

  45.                    + ", pkg=" + r.packageInfo.getPackageName()

  46.                    + ", comp=" + r.intent.getComponent().toShortString()

  47.                    + ", dir=" + r.packageInfo.getAppDir());

  48.            if (activity != null) {

  49.                Context appContext = createBaseContextForActivity(r, activity);

  50.                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());

  51.                Configuration config = new Configuration(mCompatConfiguration);

  52.                if (r.overrideConfig != null) {

  53.                    config.updateFrom(r.overrideConfig);

  54.                }

  55.                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "

  56.                        + r.activityInfo.name + " with config " + config);

  57.                Window window = null;

  58.                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {

  59.                    window = r.mPendingRemoveWindow;

  60.                    r.mPendingRemoveWindow = null;

  61.                    r.mPendingRemoveWindowManager = null;

  62.                }

  63.              //將application物件和activity進行繫結

  64.                activity.attach(appContext, this, getInstrumentation(), r.token,

  65.                        r.ident, app, r.intent, r.activityInfo, title, r.parent,

  66.                        r.embeddedID, r.lastNonConfigurationInstances, config,

  67.                        r.referrer, r.voiceInteractor, window);

  68.                if (customIntent != null) {

  69.                    activity.mIntent = customIntent;

  70.                }

  71.                r.lastNonConfigurationInstances = null;

  72.                activity.mStartedActivity = false;

  73.                int theme = r.activityInfo.getThemeResource();

  74.                if (theme != 0) {

  75.                    activity.setTheme(theme);

  76.                }

  77.                activity.mCalled = false;

  78.              //呼叫activity的onCreate()方法

  79.                if (r.isPersistable()) {

  80.                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);

  81.                } else {

  82.                    mInstrumentation.callActivityOnCreate(activity, r.state);

  83.                }

  84.                if (!activity.mCalled) {

  85.                    throw new SuperNotCalledException(

  86.                        "Activity " + r.intent.getComponent().toShortString() +

  87.                        " did not call through to super.onCreate()");

  88.                }

  89.                r.activity = activity;

  90.                r.stopped = true;

  91.                if (!r.activity.mFinished) {

  92.                    activity.performStart();

  93.                    r.stopped = false;

  94.                }

  95.                if (!r.activity.mFinished) {

  96.                    if (r.isPersistable()) {

  97.                        if (r.state != null || r.persistentState != null) {

  98.                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,

  99.                                    r.persistentState);

  100.                        }

  101.                    } else if (r.state != null) {

  102.                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);

  103.                    }

  104.                }

  105.                if (!r.activity.mFinished) {

  106.                    activity.mCalled = false;

  107.                    if (r.isPersistable()) {

  108.                        mInstrumentation.callActivityOnPostCreate(activity, r.state,

  109.                                r.persistentState);

  110.                    } else {

  111.                        mInstrumentation.callActivityOnPostCreate(activity, r.state);

  112.                    }

  113.                    if (!activity.mCalled) {

  114.                        throw new SuperNotCalledException(

  115.                            "Activity " + r.intent.getComponent().toShortString() +

  116.                            " did not call through to super.onPostCreate()");

  117.                    }

  118.                }

  119.            }

  120.            r.paused = true;

  121.            mActivities.put(r.token, r);

  122.        } catch (SuperNotCalledException e) {

  123.            throw e;

  124.        } catch (Exception e) {

  125.            if (!mInstrumentation.onException(activity, e)) {

  126.                throw new RuntimeException(

  127.                    "Unable to start activity " + component

  128.                    + ": " + e.toString(), e);

  129.            }

  130.        }

  131.        return activity;

  132.    }

進入Instrumentation類,看下activity的oncreate方法是如何呼叫的


  1.    public void callActivityOnCreate(Activity activity, Bundle icicle,

  2.            PersistableBundle persistentState) {

  3.        prePerformCreate(activity);

  4.       //activity方法呼叫

  5.        activity.performCreate(icicle, persistentState);

  6.        postPerformCreate(activity);

  7.    }


  1.    final void performCreate(Bundle icicle) {

  2.        restoreHasCurrentPermissionRequest(icicle);

  3.        onCreate(icicle);

  4.        mActivityTransitionState.readState(icicle);

  5.        performCreateCommon();

  6.    }

最後是我們熟悉的onCreate()方法


  1.    protected void onCreate(@Nullable Bundle savedInstanceState) {

  2.        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);

  3.        if (mLastNonConfigurationInstances != null) {

  4.            mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);

  5.        }

  6.        if (mActivityInfo.parentActivityName != null) {

  7.            if (mActionBar == null) {

  8.                mEnableDefaultActionBarUp = true;

  9.            } else {

  10.                mActionBar.setDefaultDisplayHomeAsUpEnabled(true);

  11.            }

  12.        }

  13.        if (savedInstanceState != null) {

  14.            Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);

  15.            mFragments.restoreAllState(p, mLastNonConfigurationInstances != null

  16.                    ? mLastNonConfigurationInstances.fragments : null);

  17.        }

  18.        mFragments.dispatchCreate();

  19.        getApplication().dispatchActivityCreated(this, savedInstanceState);

  20.        if (mVoiceInteractor != null) {

  21.            mVoiceInteractor.attachActivity(this);

  22.        }

  23.        mCalled = true;

  24.    }

總結:透過的原始碼分析,我們瞭解了一個應用程式的入口不是Activity的onCreate()方法,而是ActivityThread的main()方法,在該方法中會透過AMS來將ApplicationThread和ams進行繫結,之後又呼叫了ApplicationThread的scheduleLaunchActivity()方法透過handler傳送通知例項化activity,並最後呼叫了Activity的onCreate()方法。


原文連結:http://www.apkbus.com/blog-689749-68279.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2310/viewspace-2814189/,如需轉載,請註明出處,否則將追究法律責任。

相關文章