Activity启动过程源码分析(Android 8.0)

Activity启动过程源码分析

本文来Activity的启动流程,一般我们都是通过startActivity或startActivityForResult来启动目标activity,那么我们就由此出发探究系统是如何实现目标activity的启动的。

startActivity(new Intent(context, MainActivity.class));
startActivityForResult(new Intent(context, SecondActivity.class),1000);

一般我们都是通过上面两个函数来启动目标activity,我们来看下startActivity的源码

Activity:

@Override
public void startActivity(Intent intent) {
    this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        // Note we want to go through this call for compatibility with
>         // applications that may have overridden the method.
        startActivityForResult(intent, -1);
    }
}

我们可以看到startActivity其实也是调用startActivityForResult来启动目标activity只不过此时requestcode为-1.

Activity:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) {
    startActivityForResult(intent, requestCode, null);
}
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);//1调用Instrumentation.execStartActivity
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());//2发送请求结果
        }
        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);
        }
    }
}

在startActivityForResult中会先在注释1处调用Instrumentation.execStartActivity来获取一个ActivityResult实例,ActivityResult是用来描述目标activity执行结果的。由此我们可知activity的启动肯定跟Instrumentation.execStartActivity有关。在注释2处会调用ActivityThread.sendActivityResult来把启动结果发送出去,其最终是通过handler发送一个SEND_RESULT message,这里就不展开详述了有兴趣的自行研究。
这里解释几个类概念:
ActivityThread:它App的真正入口,当App启动后,会调用其main方法开始执行,开启消息循环队列。是传说中的UI线程,即主线程。与ActivityManagerService配合,一起完成Activity的管理工作;
Instrumentation:每一个应用程序都只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或者打开某个Activity时,都需要通过Instrumentation来进行具体的操作

下面看下Instrumentation.execStartActivity

Instrumentation:

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, String resultWho,
        Intent intent, int requestCode, Bundle options, UserHandle user) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    //...
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        //1 调用AMS的startActivity
        int result = ActivityManager.getService()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, resultWho,
                    requestCode, 0, null, options, user.getIdentifier());
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

注释1处首先调用了ActivityManager的getService()。

ActivityManager

public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @Override
            protected IActivityManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            }
        };

getService()在内部调用了IActivityManagerSingleton.get(),在get()中先通过ServiceManager.getService获取一个AMS的binder,然后调用IActivityManager.Stub.asInterface。这些操作的作用就是使用AIDL进行IPC(进程间通信)与AMS进行通信。(注意7.0及以前版本IPC的流程是:(客户端)ActivityManagerProxy -> Binder驱动 -> (服务端)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值