Activity 启动流程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mike_Cui_LS/article/details/81298647

Activity 启动调用流程 (基于5.0源码)

我们从 startActivity 开始:

startActivity()

startActivity()方法有多个重载,但是都会调用到 startActivityResult:

 public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
        if (mParent == null) {
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            ... //
         }
         ...// 省略大量代码
}

Ok,我们可以看到 调用到了 Instrumentation 的 execStartActivity 方法。

下面我们看一下 execStartActivity 中的两行重点代码:

int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);

可以看到,调用到了 ActivityManagerNative.getDefault() 的 startActivity。 而getDefault()返回的是一个 IActivityManager.

checkStartActivityResult()是校验activity 的启动结果的,比如我们没有在androidManifest 注册,等等。就会抛出异常。

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

可以看到是一个单例。IActivityManager 是一个 Binder 接口

public interface IActivityManager extends IInterface {
    ...// 方法
}

而该Binder 的真正实现 是 ActivityManagerService(简称 AMS) 。 所以接下来我们来看 AMS 中的 startActivity实现

 @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, options,
            UserHandle.getCallingUserId());
    }

啥实事也没干,直接转调了 startActivityAsUser 继续跟进,

 @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, options, userId, null, null);
    }

该方法调了 ActivityStackSupervisorstartActivityMayWait 方法。 在该方法中又调用了自身的 startActivityLocked 方法,该方法中又调用到 startActivityUncheckedLocked() 又从该方法调用到了 ActivityStack 的 resumeTopActivityLocked 方法。这时 已经从 ActivityStackSupervisor 转到了 ActivityStack

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        if (inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            inResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            inResumeTopActivity = false;
        }
        return result;
    }

上面代码看到 resumeTopActivityLocked 调用了 resumeTopActivityInnerLocked 在该方法中:

  mStackSupervisor.startSpecificActivityLocked(next, true, false);

又回到了 ActivityStackSupervisor 中, ok, startSpecificActivityLocked 中 调用了 realStartActivityLocked 看到这个名字,说明我们已经差不多了。 该方法的关键代码如下:

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

那么app.thread 是什么呢?? 它是 IApplicationThread 类型。

public interface IApplicationThread extends IInterface {}

是一个Binder 接口。 AMS进程通过该 binder接口 来调用 app进程的方法。

IApplicationThread 的实现 是在 ActivityThread 中的 ApplicationThread , IApplicationThread 中定义了很多接口方法。都是和四大组件相关的

    void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
            int configChanges, boolean dontReport) throws RemoteException;
    void scheduleStopActivity(IBinder token, boolean showWindow,
            int configChanges) throws RemoteException;
    void scheduleWindowVisibility(IBinder token, boolean showWindow) throws RemoteException;
    void scheduleSleeping(IBinder token, boolean sleeping) throws RemoteException;
    void scheduleResumeActivity(IBinder token, int procState, boolean isForward, Bundle resumeArgs)
            throws RemoteException;
    void scheduleSendResult(IBinder token, List<ResultInfo> results) throws RemoteException;
    void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
            IVoiceInteractor voiceInteractor, int procState, Bundle state,
            PersistableBundle persistentState, List<ResultInfo> pendingResults,
            List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
            ProfilerInfo profilerInfo) throws RemoteException;
    void scheduleRelaunchActivity(IBinder token, List<ResultInfo> pendingResults,
            List<Intent> pendingNewIntents, int configChanges,
            boolean notResumed, Configuration config) throws RemoteException;
    void scheduleNewIntent(List<Intent> intent, IBinder token) throws RemoteException;

    ......

ok 我们来看 ApplicationThread 的实现.

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

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            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;

            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

scheduleLaunchActivity 中保存了启动Activity的相关信息,然后 发送了一个消息 H.LAUNCH_ACTIVITY 这里呢,我们就需要提一下这个 H .

 final H mH = new H();

H 继承自Handler。负责系统消息的处理。 消息的处理是在 handleMessage 方法中。 至于这里为什么要使用Handler 。 因为之前的操作 都是在服务端的 Binder 线程池中,所以我们这里需要切换到主线程。 handleMessage中的 调用了 handleLaunchActivity 方法。 而该方法 又调用了 performLaunchActivity方法.

该方法中做了如下几件事:

1.从ActivityClientRecord 中取出 待启动的Activity 的组件信息。

  ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        ComponentName component = r.intent.getComponent();
        if (component == null) {
            component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
            r.intent.setComponent(component);
        }

        if (r.activityInfo.targetActivity != null) {
            component = new ComponentName(r.activityInfo.packageName,
                    r.activityInfo.targetActivity);
        }

2.通过Instrumentation 的 newActivity 方法 使用类加载器创建 Activity 对象

        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

3.通过LoadedApk 的 makeApplication 方法来尝试创建 Application对象。

4.创建ContextImpl 对象并通过Activity 的 attach 方法来完成一些重要数据的初始化

  Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.voiceInteractor);

ContextImpl 是context 的具体实现,Context 中的大部分逻辑都是由 ContextImpl 来实现的。 ContextImpl 是通过 Activity 的 attach 方法 来和 Activity 建立关联的。 而且 attach 方法中 还会完成 Window 的创建 并建立和 Winwod 的关联。 这样当Window 接收到外部输入事件后就可以传递给Activity 了。

5.调用Activity 的 OnCreate 方法。

 if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }

整体总结:

当启动一个Activity时,会通过 Instrumentation 类来 execStartActivity来启动,该类 可以看作是一个管家。里面有很多 关于 Activity 生命周期的方法,可以看作是一个中间件。 在该方法中会 调用 IActivityManager 中的 startActivity 。该接口是个Binder接口,真正的实现是 服务端的 AMS, 在ams 中会 涉及到两个类 ActivityStackSupervisor 和 ActivityStack 处理 Activity 相关的启动逻辑。 当准备好后, 会调用 app.thread.scheduleLaunchActivity(). app.thread 的类型是 IApplicationThread 接口,是个Binder 接口。真正的实现类是 ApplicationThread 。 在 scheduleLaunchActivity 中进行了数据的存储,然后发送 LAUNCH_ACTIVITY 的消息,由 H 。 H 继承自Handler。 此处由于AMS 端的调用是在 binder 线程池,所以要切换到主线程。 在 handleMessage 中进行了相关的 Activity的创建、初始化、以及 OnCreate 的调用。

简记:

Handler 在Android 中线程通讯起着很大的作用, Framework 层有很多的Handler,运行在不同的线程; 而我们应用层也有一个比较重要的Handler,即 ActivityThread 中的 mH. 运行在 ui 线程。

ApplicationThread 为 IApplicationThread 的具体实现类, 用来接收服务端的消息, 四大组件就是通过 ApplicationThread 来接收服务端的消息的。

ActivityStarter 处理一些 intent 和 flag 。 然后交给ActivityStackSupervisor 和 ActivityStack 来处理被调用Activity 的进程进栈。 如果被调用者的进程存在,就会使用 ApplicationThread 这个客户端的 Binder 通知已存在的调用者进程启动Activity, 如果不存在,就会使用 Socket 通知 Zygote 进程 fork 出一个进程,用来承载即将启动的Activity。

ActivityStarter : intent 和 flag 如何打开Activity

ActivityStack: 管理Activity

ActivityStack 管理Activity的方法:

startActivityLocked()
resumeTopActivityLocked()
completeResumeLocked()
startPausingLocked()
completePauseLocked()
stopActivityLocked()
activityPausedLocked()
finishActivityLocked()
activityDestroyedLocked()

猜你喜欢

转载自blog.csdn.net/mike_Cui_LS/article/details/81298647