Android全集Android开发

第9章 四大组件的工作过程

2019-05-15  本文已影响0人  littlefogcat

所谓四大组件是Activity、Service、BroadcastReceiver、ContentProvider。了解了他们的工作流程,可以更好的理解Android体系结构。

9.1 Activity

我们经常使用Activity#startActivity(intent)方法来启动一个Activity。startActivity()方法有许多重载,但是最后都会调用到startActivityForResult(Intent, int, Bundle)。

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

而Activity启动的实际执行是这一句mInstrumentation.execStartActivity(...);继续跟踪:

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        // ……
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

看到这一句:int result = ActivityManager.getService().startActivity(...);
ActivityManager.getService()获取到的是一个实现了IActivityManager接口的Binder(这里跟书中有一些出入,应该是sdk版本的差异,我使用的是api 27,ActivityManagerNative类已经deprecated了),与系统的AMS进行IPC通信。从这里我们可以看出,Activity的启动实际上交给了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 bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }

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

这里开始的流程跟书中就不一样了,启动过程交由ActivityStarter这个类处理,经历startActivityMayWait() -> startActivityLocked() -> startActivity() -> startActivityUnchecked()
在startActivityUnchecked()这个方法中,有这么两句:

mTargetStack.startActivityLocked(mStartActivity, topFocused, 
            newTask, mKeepCurTransition, mOptions);

mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, 
            mStartActivity, mOptions);

第一句会将待启动的Activity添加到栈中;第二句会依次调用ActivityStack.resumeTopActivityUncheckedLocked() -> ActivityStack.resumeTopActivityInnerLocked() -> ActivityStackSupervisor.startSpecificActivityLocked()
流程到这里就又跟书上面的一样了。版本的更新修改了一些细节的实现,但是大体的流程还是一样的。

最终,会调用ApplicationThread的scheduleLaunchActivity方法来启动Activity。ApplicationThread是ActivityThread的内部类,它也是一个Binder。scheduleLaunchActivity方法会通过Handler发送消息,调用ActivityThread的handleLaunchActivity方法,这个方法在第四章的时候做了简单的分析,它会调用performLaunchActivity方法。performLaunchActivity主要做了几件事:

  1. 获取待启动Activity的组件信息;
  2. 通过Instrumentation创建Activity对象;
  3. 如果还没有Application对象,那么创建它;
  4. 创建BaseContext、Window,并和Activity进行绑定attach;
  5. 调用Activity的onCreate方法。

说实话看到这里,我已经有些模糊了。不如画个流程图来归纳一下。

Activity启动流程.jpg

至此,Activity就已经创建完毕并且启动了。
// TODO 仔细研究一下Instrumentation以及AMS

上一篇 下一篇

猜你喜欢

热点阅读