Activity启动源码分析-基于Android10(一)

文章目录

前言

之前对于启动Activity有所了解,但是自觉了解不深,而且很容易忘记,本着"好记性不如烂笔头“这里记录下启动流程。本文章参考Android Open Source Project

总流程图(网络图片)
总流程

  • Instrumentation
    负责调用Activity和Application生命周期。
  • ActivityTaskManagerService
    负责Activity管理和调度等工作。android10中新增的
  • ActivityManagerService
    负责管理四大组件和进程,包括生命周期和状态切换。
  • ActivityTaskManagerInternal
    ActivityTaskManagerService对外提供的一个抽象类,真正的实现在ActivityTaskManagerService#LocalService
  • ActivityThread
    管理应用程序进程中主线程的执行
  • ActivityStackSupervisor
    负责所有Activity栈的管理
  • TransactionExecutor
    主要作用是执行ClientTransaction
  • ClientLifecycleManager
    生命周期的管理调用

Activity启动

在启动Activity的时候,无论是点击桌面的图标,还是自己写的App中启动Activity,最后都是归结到Activity的startActivityForResult方法。其实点击桌面的图标,也是依靠Launcher程序去打开Activity的,和我们使用startActivity方法去启动Activity是没有任何区别的。

frameworks\base\core\java\android\app\Activity.java

    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            // 注意getApplicationThread方法
            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) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

无论如何startActivity,最后调用的是startActivityForResult方法。该方法最后调用了Instrumentation的execStartActivity方法。注意这句代码:

mMainThread.getApplicationThread()

mMainThread实际上是ActivityThread类,而这个类就是传说中的”主线程“。那么getApplicationThread的值是什么呢?通过系统源码可以得知它是ActivityThread的内部类ApplicationThread

frameworks\base\core\java\android\app\ActivityThread.java

	@UnsupportedAppUsage
    public ApplicationThread getApplicationThread()
    {
        return mAppThread;
    }

ApplicationThread类继承了IApplicationThread.Stub,熟悉AIDL的都知道,这个类是Android通过IApplicationThread.aidl自己生成的的类。
部分ApplicationThread代码:

frameworks\base\core\java\android\app\ActivityThread.java

//...省略部分代码
private class ApplicationThread extends IApplicationThread.Stub {
        private static final String DB_INFO_FORMAT = "  %8s %8s %14s %14s  %s";

        public final void scheduleSleeping(IBinder token, boolean sleeping) {
            sendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
        }

        public final void scheduleReceiver(Intent intent, ActivityInfo info,
                CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
                boolean sync, int sendingUser, int processState) {
            updateProcessState(processState, false);
            ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
                    sync, false, mAppThread.asBinder(), sendingUser);
            r.info = info;
            r.compatInfo = compatInfo;
            sendMessage(H.RECEIVER, r);
        }

        public final void scheduleCreateBackupAgent(ApplicationInfo app,
                CompatibilityInfo compatInfo, int backupMode, int userId) {
            CreateBackupAgentData d = new CreateBackupAgentData();
            d.appInfo = app;
            d.compatInfo = compatInfo;
            d.backupMode = backupMode;
            d.userId = userId;

            sendMessage(H.CREATE_BACKUP_AGENT, d);
        }
	//...省略部分代码

而IApplicationThread.aidl恰恰是ActivityManagerService和App通讯的桥梁,后面的文章将会谈到,顺便一提,老版本用的是ActivityManagerService,新版本改为ActivityTaskManagerService。
这里的Instrumentation对象和ActivityThread对象都是通过Activity的attach方法获取到的,Instrumentation对象是每创建一个Activity都会提供一个引用。

frameworks\base\core\java\android\app\ActivityThread.java

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
		//...省略部分代码
		Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.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);
            }
        }
        //...省略部分代码
        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, window, r.configCallback,
                        r.assistToken);
                //...省略部分代码
            }
}
frameworks\base\core\java\android\app\Activity.java

// 注意Instrumentation instr和IBinder token
// IBinder token就是IApplicationThread
final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback) {
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);

        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
            mWindow.setSoftInputMode(info.softInputMode);
        }
        if (info.uiOptions != 0) {
            mWindow.setUiOptions(info.uiOptions);
        }
        mUiThread = Thread.currentThread();

        mMainThread = aThread;
        mInstrumentation = instr;
        mToken = token;
        mIdent = ident;
        mApplication = application;
        mIntent = intent;
        mReferrer = referrer;
        mComponent = intent.getComponent();
        mActivityInfo = info;
        mTitle = title;
        mParent = parent;
        mEmbeddedID = id;
        mLastNonConfigurationInstances = lastNonConfigurationInstances;
        if (voiceInteractor != null) {
            if (lastNonConfigurationInstances != null) {
                mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
            } else {
                mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                        Looper.myLooper());
            }
        }

        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;

        mWindow.setColorMode(info.colorMode);

        setAutofillCompatibilityEnabled(application.isAutofillCompatibilityEnabled());
        enableAutofillCompatibilityIfNeeded();
    }

attach方法向Activity里面添加了很多重要的参数,比如Context,ActivityThread,application等等。至于attach何时被执行,在Activity启动源码分析-基于Android10(二)这篇文章将做分析。

下一篇:Activity启动源码分析-基于Android10(二)

参考文章:Activity的启动流程-基于Android10源码

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rockyou666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值