继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Android源码解析之ActivityThread,深入了解应用程序的入口

繁花如伊
关注TA
已关注
手记 401
粉丝 40
获赞 295
  • 在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("<pre-initialized>");

  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("<pre-initialized>",

  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<ProviderInfo> 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<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 (!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 /* deferResume */);

  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 < 0) {

  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<ResultInfo> results = null;

  53.            List<ReferrerIntent> 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<ResultInfo> pendingResults, List<ReferrerIntent> 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

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP