Android源码解析四大组件系列(四)---Activity启动详细流程

在上一篇博客http://www.jianshu.com/p/98fa08ee1bfb,我们起码知道了Zygote是怎么启动SystemServer进程的,AMS是怎么注册的,启动的,启动之后通过Socket怎样与Zygote进程通信的,而Zygote进程收到AMS的请求之后,是怎么fork进程,将ActivityThread的main方法是执行起来的。这些内容在我的前两篇博客都梳理过,建议阅读一下,在看本文。

一、Activity请求启动

Android源码解析四大组件系列(四)---Activity启动详细流程_第1张图片

我们以startActivity这种来分析

  Intent intent=new Intent(MainActivity.this,TargetActivity.class);
  startActivity(intent);

经过startActivity–>startActivityForResult–>execStartActivity,最终会调用Instrumentation的execStartActivity方法。

 public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        Uri referrer = target != null ? target.onProvideReferrer() : null;
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
       .....

        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            //获取AMS的代理,启动Activity
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);

            //检查Activity是否启动成功,若失败给出是什么原因
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;

    }

这些参数的意思是

  • this,为启动Activity的对象;
  • contextThread,为Binder对象,是主进程的context对象;
  • token,也是一个Binder对象,指向了服务端一个ActivityRecord对象;
  • target,为启动的Activity;
  • intent,启动的Intent对象;
  • requestCode,请求码;
  • options,参数;

先看checkStartActivityResult方法的实现

 public static void checkStartActivityResult(int res, Object intent) {
        if (res >= ActivityManager.START_SUCCESS) {
            return;
        }

        switch (res) {
            case ActivityManager.START_INTENT_NOT_RESOLVED:
            case ActivityManager.START_CLASS_NOT_FOUND:
                if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                    throw new ActivityNotFoundException(
                            "Unable to find explicit activity class "
                            + ((Intent)intent).getComponent().toShortString()
                            + "; have you declared this activity in your AndroidManifest.xml?");
                throw new ActivityNotFoundException(
                        "No Activity found to handle " + intent);
            case ActivityManager.START_PERMISSION_DENIED:
                throw new SecurityException("Not allowed to start activity "
                        + intent);
            case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
                throw new AndroidRuntimeException(
                        "FORWARD_RESULT_FLAG used while also requesting a result");
            case ActivityManager.START_NOT_ACTIVITY:
                throw new IllegalArgumentException(
                        "PendingIntent is not an activity");
            case ActivityManager.START_NOT_VOICE_COMPATIBLE:
                throw new SecurityException(
                        "Starting under voice control not allowed for: " + intent);
            case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
                throw new IllegalStateException(
                        "Session calling startVoiceActivity does not match active session");
            case ActivityManager.START_VOICE_HIDDEN_SESSION:
                throw new IllegalStateException(
                        "Cannot start voice activity on a hidden session");
            case ActivityManager.START_CANCELED:
                throw new AndroidRuntimeException("Activity could not be started for "
                        + intent);
            default:
                throw new AndroidRuntimeException("Unknown error code "
                        + res + " when starting " + intent);
        }
    }

常见的ActivityNotFoundException,SecurityException等错日志就在这里报出来的。

OK,现在回到execStartActivity,内部调用了ActivityManagerNative.getDefault().startActivity,关于ActivityManagerNative已经说了很多了,相当于AMS服务端存根或者代理,其客户端是ActivityManagerNative的内部类ActivityManagerProxy,这里getDefault获取的就是ActivityManagerProxy对象,通过ActivityManagerProxy对象来使用AMS内部的一些服务,包括单不限于启动Activity。所以通过ActivityManagerProxy对象调用startActivity方法的实质是调用BinderProxy.transact向Binder驱动发送START_ACTIVITY_TRACSACTION命令,binder驱动将处理逻辑从Launcher所在的进程切换到AMS所在的SystemServer进程。OK,我们直接看ActivityManagerService的startActivity方法,不明白,建议看一下Binder的通信原理。

二、AMS处理Activity的启动请求

2.1、AMS处理Activity的启动请求
    @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

保持篇幅,以下步骤省略。
ActvityiManagerService.startActivityAsUser()
ActivityStackSupervisor.startActivityMayWait()
ActivityStackSupervisor.startActivityLocked()
ActivityStackSupervisor.startActivityUncheckedLocked()
ActivityStackSupervisor.startActivityLocked()
ActivityStackSupervisor.resumeTopActivitiesLocked()
ActivityStackSupervisor.resumeTopActivityInnerLocked()

在resumeTopActivityInnerLocked的内部有如下代码。

 if (mResumedActivity != null) {
         if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
         pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
 }

这表明在启动一个Activity的时候,前面一个Activity要执行onPause方法,onPause方法是怎么调用的呢?

2.2、AMS调用栈顶Activity的onPause
 final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
            boolean dontWait) {
        ......
        if (mService.mHasRecents && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
            prev.updateThumbnailLocked(screenshotActivities(prev), null);
        }
        stopFullyDrawnTraceIfNeeded();

        mService.updateCpuStats();

        if (prev.app != null && prev.app.thread != null) {
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
            try {
               //调用ApplicationThread的schedulePauseActivity
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, dontWait);
            } catch (Exception e) {
             ......
            }
        }

       ......
    }

这里先留一个问题, 我知道prev.app.thread是ApplicationThreadProxy对象,实际是调用了ApplicationThread的schedulePauseActivity方法,但是AMS是怎么获取到prev.app.thread的呢?

    public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges, boolean dontReport) {
            sendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
                    configChanges);
        }

关键就是最后调用了sendMessage(H.BIND_APPLICATION, data),发送了消息。关于H这个类,其实是个Hander,我觉得它的作用就像是一个交通枢纽。对这个H想更详细了解的,详细戳我。H接收到这个Message之后,调用

  handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,   (msg.arg1&2) != 0);
    private void handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport) {
        ActivityClientRecord r = mActivities.get(token);
            .......
            r.activity.mConfigChangeFlags |= configChanges;
            performPauseActivity(token, finished, r.isPreHoneycomb());
            .......

            // Tell the activity manager we have paused.
            if (!dontReport) {
                try {
                    ActivityManagerNative.getDefault().activityPaused(token);
                } catch (RemoteException ex) {
                }
            }
            mSomeActivitiesChanged = true;
        }
    }
    final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
            boolean saveState) {
        if (r.paused) {
         .......
        try {
          .......
            //调用Instrumentation的callActivityOnPause方法
            mInstrumentation.callActivityOnPause(r.activity);
            EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
                    r.activity.getComponentName().getClassName());
            if (!r.activity.mCalled) {
                throw new SuperNotCalledException(
                    "Activity " + r.intent.getComponent().toShortString() +
                    " did not call through to super.onPause()");
            }

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            .......
            }
        }
        r.paused = true;

         .......
        return !r.activity.mFinished && saveState ? r.state : null;
    }
  public void callActivityOnPause(Activity activity) {
        activity.performPause();
    }
   final void performPause() {
        mDoReportFullyDrawn = false;
        mFragments.dispatchPause();
        mCalled = false;
        //onPause执行
        onPause();
        mResumed = false;
        if (!mCalled && getApplicationInfo().targetSdkVersion
                >= android.os.Build.VERSION_CODES.GINGERBREAD) {
            throw new SuperNotCalledException(
                    "Activity " + mComponent.toShortString() +
                    " did not call through to super.onPause()");
        }
        mResumed = false;
    }

分析到这里 onPause()终于执行了。回到 handlePauseActivity方法中,在这个方法最后调用了ActivityManagerNative.getDefault().activityPaused(token)

2.3、ActivityManagerService的activityPaused方法执行。
  @Override
    public final void activityPaused(IBinder token) {
        final long origId = Binder.clearCallingIdentity();
        synchronized(this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                stack.activityPausedLocked(token, false);
            }
        }
        Binder.restoreCallingIdentity(origId);
    }

经过一些方法,最终会调用startSpecificActivityLocked
ActivityStack.activityPausedLocked()
ActivityStack.completePauseLocked()
ActivityStackSupervisor.resumeTopActivitiesLocked()
ActivityStack.resumeTopActivityLocked()
ActivityStack.resumeTopActivityInnerLocked ()
ActivityStack.startSpecificActivityLocked ()

  void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.task.stack.setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

如果需要启动的Activity所需要的应用进程是否已经启动,如果没有则执行realStartActivityLocked去启动Activity,否则去启动启动应用进程,相当于一个预启动的过程。

2.4、应用进程创建

关于startProcessLocked怎么执行的,上篇博客分析过,SystemServer进程中Ams通过Socket与Zygote进程进行通信的,Zygote接收到AMS发起的创建进程的请求,会fork出一个子进程,并且反射调用这个进程中ActivityThread的main方法。详情步骤戳我,在应用进程启动之后,ActivityThread的main方法就开始执行了。

三、ActivityThread的main方法执行

在ActivityThread的main方法里调用thread.attach(false);

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

        Process.setArgV0("");

        Looper.prepareMainLooper();

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

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

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

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

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

对于上面main方法,相信很多人都看多很多遍了,接下来重点分析 thread.attach(false)这行代码。

 private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
             .......

        //获取ActivityManagerService在客户端的代理
            IActivityManager mgr = ActivityManagerNative.getDefault();
            try {

        //实质是调用ActivityManagerService的attachApplication方法,目的是让ActivityManagerService通过ApplicationThread代理对象控制应用进程
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
            }
        }
    .......
    }

在调用 mgr.attachApplication()的时候,将mAppThread对象传进去了。

   final ApplicationThread mAppThread = new ApplicationThread();

ApplicationThread继承了ApplicationThreadNative, 看一下ApplicationThreadNative里面的方法。

Android源码解析四大组件系列(四)---Activity启动详细流程_第2张图片

内部调用了ActivityManagerNative.getDefault() .attachApplication,关于ActivityManagerNative已经说了很多了,相当于AMS服务端存根或者代理,其客户端是ActivityManagerNative的内部类ActivityManagerProxy,这里getDefault获取的就是ActivityManagerProxy对象,通过ActivityManagerProxy对象来使用AMS内部的一些服务,包括单不限于启动Activity。所以通过ActivityManagerProxy对象调用attachApplication方法的实质是调用BinderProxy.transact向Binder驱动发送ATTACH_APPLICATION_TRANSACTION命令,binder驱动将处理逻辑从APP应用进程所在的进程切换到AMS所在的SystemServer进程。OK,我们直接看ActivityManagerService的attachApplication方法:

    @Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }
private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
        ProcessRecord app;
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                //通过进程ID,获取进程的记录信息
                app = mPidsSelfLocked.get(pid);
            }
        } else {
            app = null;
        }

        if (app == null) {
            Slog.w(TAG, "No pending application record for pid " + pid
                    + " (IApplicationThread " + thread + "); dropping process");
            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
            if (pid > 0 && pid != MY_PID) {
                //如果没有获取到,需要杀死该进程,MY_PID是系统进程
                Process.killProcessQuiet(pid);

            } else {
                 ......
            return false;
        }

        ......
    //获取进程名称
        final String processName = app.processName;
        try {
            AppDeathRecipient adr = new AppDeathRecipient(
                    app, pid, thread);
            thread.asBinder().linkToDeath(adr, 0);
            app.deathRecipient = adr;
        } catch (RemoteException e) {
            app.resetPackageList(mProcessStats);
            startProcessLocked(app, "link fail", processName);
            return false;
        }

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

    //设置进程的OOM,adj等值

        //还记得上面留下的那个问题吗,AMS是怎么获取到prev.app.thread的呢?就在这,prev.app是ProcessRecord对象,makeActive内部将thread对象赋值给prev.app.thread。可以自己查阅,这样AMS是可以查询进程记录的,进程记录中就有一个app.thread,若AMS要跟Activity通信直接获取prev.app.thread就可以了。
        app.makeActive(thread, mProcessStats);
        app.curAdj = app.setAdj = -100;
        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
        app.forcingToForeground = null;
        updateProcessForegroundLocked(app, false, false);
        app.hasShownUi = false;
        app.debugging = false;
        app.cached = false;
        app.killedByAm = false;

        //将attach之前的超时Meessage移除掉
        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);

        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;

          ......
        try {
          ......
            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());
            updateLruProcessLocked(app, false, null);
            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
        } catch (Exception e) {
            // todo: Yikes!  What should we do?  For now we will try to
            // start another process, but that could easily get us in
            // an infinite loop of restarting processes...
            Slog.wtf(TAG, "Exception thrown during bind of " + app, e);

            app.resetPackageList(mProcessStats);
            app.unlinkDeathRecipient();
            startProcessLocked(app, "bind fail", processName);
            return false;
        }

       ......

    // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }

        // 执行等待进程而暂时挂起的Service
        if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                badApp = true;
            }
        }

        // 执行等待进程而暂时挂起的广播
        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
            try {
                didSomething |= sendPendingBroadcastsLocked(app);
            } catch (Exception e) {
                // If the app died trying to launch the receiver we declare it 'bad'
                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
                badApp = true;
            }
        }



        ......

        if (!didSomething) {
        //调整进程优先级adj的值
            updateOomAdjLocked();
        }

        return true;
    }

发现AMS用IApplicationThread对象thread调用了bindApplication,thread实际上就是ApplicationThreadProxy对象。AMS通过ApplicationThreadProxy对象与ActivityThread通信。所以去ApplicationThread中看bindApplication的真正实现。

  public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
                Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,
                Bundle coreSettings) {

            if (services != null) {
                // Setup the service cache in the ServiceManager
                ServiceManager.initServiceCache(services);
            }

            setCoreSettings(coreSettings);
            ......
            AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;
            data.providers = providers;
            data.instrumentationName = instrumentationName;
            data.instrumentationArgs = instrumentationArgs;
            data.instrumentationWatcher = instrumentationWatcher;
            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
            data.debugMode = debugMode;
            data.enableOpenGlTrace = enableOpenGlTrace;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            sendMessage(H.BIND_APPLICATION, data);
        }

这里又是用H发送了一个消息,是不是很像一个交通枢纽,做转发用的。详细戳我。

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,  "bindApplication");
   AppBindData data = (AppBindData)msg.obj;
    handleBindApplication(data);
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

handleBindApplication内部就不分析了,Applcation对象的onCreate方法调用就是在这里面,它内部创建了Applcation对象。

四、Activity周期如何执行

4.1、Activity的onCreate是怎么回调的

回到第二小节的startSpecificActivityLocked方法

  void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.task.stack.setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {

                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

在预启动之后,一般我们的应用进程就被孵化来了,直接执行realStartActivityLocked去启动Activity。

在realStartActivityLocked内部调用了如下代码,现在你应该知道 app.thread是什么了。

 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

直接到scheduleLaunchActivity真正实现,它的真正实现是在Applciation中的。

  public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List pendingResults, List pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.persistentState = persistentState;

            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;
            r.isForward = isForward;

            r.profilerInfo = profilerInfo;

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

经过一堆的变量赋值之后,又通过H发送了一个消息LAUNCH_ACTIVITY,H在收到这个消息之后,执行下面。

  Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
  final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

 r.packageInfo = getPackageInfoNoCheck(
 r.activityInfo.applicationInfo, r.compatInfo);
 handleLaunchActivity(r, null);
 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
        mSomeActivitiesChanged = true;

        if (r.profilerInfo != null) {
            mProfiler.setProfiler(r.profilerInfo);
            mProfiler.startProfiling();
        }

        // Make sure we are running with the most recent config.
        handleConfigurationChanged(null, null);

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

        // Initialize before creating the activity
        WindowManagerGlobal.initialize();

         //一个 perform开头的方法,启动Activity
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            Bundle oldState = r.state;
            //Launch
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);

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

                try {
                    r.activity.mCalled = false;

                    mInstrumentation.callActivityOnPause(r.activity);

                    if (r.isPreHoneycomb()) {
                        r.state = oldState;
                    }
                    if (!r.activity.mCalled) {
                        throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                            " did not call through to super.onPause()");
                    }

                } catch (SuperNotCalledException e) {
                    throw e;

                } catch (Exception e) {
                     .....
                }
                r.paused = true;
            }
         .....
        }
    }

这个方法会将Activity创建出来。

  private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

        ActivityInfo aInfo = r.activityInfo;
         r.activityInfo.targetActivity);

        ......
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();

            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
          .......
        } catch (Exception e) {
             .......
        }

       Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
        if (activity != null) {     
        activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor);
             .......
    //Activity的create方法执行
          if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
   .......

        r.activity = activity;
                r.stopped = true;
                if (!r.activity.mFinished) {
                //Activity的start方法执行
                    activity.performStart();
                    r.stopped = false;
                }
        mActivities.put(r.token, r);

        return activity;
    }

反射创建Activity,为啥要用反射呢,此处搞不清楚。

    public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
    }

解析来mInstrumentation调用callActivityOnCreate方法。

   public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState);
        postPerformCreate(activity);
    }
  final void performCreate(Bundle icicle) {
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

onCreate方法在此处被调用了。

4.2、Activity的onStart是怎么回调的

在performLaunchActivity中调用了callActivityOnCreate之后,又会调用 activity.performStart()

 final void performStart() {
        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
        mFragments.noteStateNotSaved();
        mCalled = false;
        mFragments.execPendingActions();
        mInstrumentation.callActivityOnStart(this);
        if (!mCalled) {
            throw new SuperNotCalledException(
                "Activity " + mComponent.toShortString() +
                " did not call through to super.onStart()");
        }
        mFragments.dispatchStart();
        mFragments.reportLoaderStart();
        mActivityTransitionState.enterReady(this);
    }
 public void callActivityOnStart(Activity activity) {
        activity.onStart();
    }

到此处start方法又被调用了。

4.3、Activity的onResume是怎么回调的

handleLaunchActivity方法中,在调用performLaunchActivity之后,调用了handleResumeActivity方法。

ActivityThread.handleResumeActivity()
ActivityThread.handleResumeActivity()
Activity.performResume()
 Instrumentation.callActivityOnResume();
    public void callActivityOnResume(Activity activity) {
        activity.mResumed = true;
        activity.onResume();

        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; ifinal ActivityMonitor am = mActivityMonitors.get(i);
                    am.match(activity, activity, activity.getIntent());
                }
            }
        }
    }

到此Activity的onResume方法被调用,onPause方法已经讲解过,关于onStop,onDestory一样的套路分析。

五、总结

关于Activity的启动过程分析,三篇文章都分析完了,现在以一张图总结一下。

Android源码解析四大组件系列(四)---Activity启动详细流程_第3张图片

  • 启动一个Activity的方式有多种,都是通过向Ams发送startActivity请求

  • Ams在启动Activity的时候,会判断目标进程有没有被创建,没有创建的话,向zygote进程发送创建进程的请求;

  • Zygote进程fork出新的子进程,即App进程;

  • App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;

  • AMS所在的SystemServer进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;

  • App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;

  • 主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。

上图大致说明了一个Activity的启动流程, 重点在于把握Binder的通信原理,接着弄清楚APP进程,SystemServer进程,Zygote进程是怎么互相通信的。seeyou!

参考博客:
http://gityuan.com/2016/03/12/start-activity/

你可能感兴趣的:(Android源码解析,Android源码解析)