Activity的启动流程

                 很早之前就想写一篇关于Activity启动流程的文章,但是很多时候都很难坚持下来,一个是因为工作比较忙的原因,第二个是因为Activity的启动流程太过复杂,不敢轻易下手。最近一段时间公司不忙,加上自己有大把的时间去研究源码,所以便把Activity的启动流程再次好好看了一遍,顺便记录下来供以后自己复习。

 

 一般开始进入Activity的源码分析是从Activity$startActivity开始的,但是其实真正的入口却并不是这个,而是Activity$main()方法,所以我们先来看看Activity$main()方法里面做了些什么事情

public static void main(String[] args) {
    
        // 初始化Looper对象  
        Looper.prepareMainLooper();

        // 创建ActivityThread
        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        // 开始循环
        Looper.loop();

}

看看thread.attach(false);里面做了些什么事情

private void attach(boolean system) {
    // 省略部分代码
    // IActivityManager是一个接口,具体的实现类是ActivityManagerService
    final IActivityManager mgr = ActivityManager.getService();
    try {
        // mAppThread是ActivityThread类里面的一个内部类
        mgr.attachApplication(mAppThread);
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
    // 省略部分代码
}

那么ActivityManagerService是什么呢?

ActivityManagerService简称AMS,它是android中很重要的一个服务,它统筹管理着android的四大组件;统一调度各应用进程;AMN由Binder类派生,实现了IActivityManager接口,客户端使用ActivityManager类,因为AMS是系统核心服务,很多API不能直接访问,需要通过ActivityManager来进行处理

 

好,那么我们现在开始进入正题

// 我们调用的startActivity最终都会执行到这里
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
    //  Instrumentation和Activity有点类似,只不过Activity是需要一个界面的,而Instrumentation并不是这样的
    //  我们可以将它理解为一种没有图形界面的,具有启动能力的,用于监控其他类(用Target Package声明)的工具类
    //  注意mMainThread.getApplicationThread()获取的是ApplicationThread的实例
    Instrumentation.ActivityResult ar =
        mInstrumentation.execStartActivity(
            this, mMainThread.getApplicationThread(), mToken, this,
            intent, requestCode, options);
}

进入到Instrumentation里面的execStartActivity

 public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        // 省略部分代码
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            // ActivityManager.getService().startActivity方法最终会执行到ActivityManagerService()方法里面的startActivity
            // 需要注意的是这里通过binder已经进行了一次跨进程通信
            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;
}

进入到ActivityManagerService里面的startActivity()

@Override
public int startActivity(IBinder whoThread, String callingPackage,
                Intent intent, String resolvedType, Bundle bOptions) {
            checkCaller();

            int callingUser = UserHandle.getCallingUserId();
            TaskRecord tr;
            IApplicationThread appThread;
            synchronized (ActivityManagerService.this) {
                tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
                if (tr == null) {
                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
                }
                // 注意这里的跨进程采用的方式是AIDL
                appThread = IApplicationThread.Stub.asInterface(whoThread);
                if (appThread == null) {
                    throw new IllegalArgumentException("Bad app thread " + appThread);
                }
            }
            return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
                    resolvedType, null, null, null, null, 0, 0, null, null,
                    null, bOptions, false, callingUser, tr, "AppTaskImpl");
}

进入到ActivityManagerService里面的startActivityMayWait()

final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult,
            Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
            TaskRecord inTask, String reason) {
            // 省略部分代码
            int res = startActivityLocked(caller, 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值