APP启动流程分析(下)

前言

本文基于Android 9.0(Android P),API 28。
本文是APP启动流程分析的下篇,走源码流程。
如果想了解总体流程,请看上篇APP启动流程分析(上)

总流程

在这里插入图片描述
总流程分成三个阶段

Launcher请求AMS阶段

在这里插入图片描述

AMS到ApplicationThread阶段

在这里插入图片描述

ApplicationThread到Activity阶段

在这里插入图片描述

上图中的序号,会在下面的源码中标记

源码解析

Launcher请求AMS阶段

Launcher也是APP,从Launcher点击一个APP图标,也是用startActivity。

     //1 进去
     startActivity(intent);

我们点进去startActivity,来到

1 Activity的startActivity方法

  @Override
    public void startActivity(Intent intent) {
   
        this.startActivity(intent, null);
    }

再点进去

    @Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
   
        if (options != null) {
   
            //2 进去
            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);
        }
    }

2 Activity的startActivityForResult方法

 public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
   
        if (mParent == null) {
   
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                    //mMainThread.getApplicationThread()是ApplicationThread,APP那边Binder的代理类,等下传递给AMS
                    //3 进去
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
                    
      省略代码....
          
    }

3 Instrumentation的execStartActivity方法

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
   
            
      省略代码......
      
      try {
   
            //合并Intent的参数
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            //ActivityManager.getService()得到了IActivityManager
            //调用IActivityManager的startActivity方法 4
            //IActivityManager是AMS的代理类,用于APP与AMS进行Binder通信
            //所以跳到ActivityManagerService的startActivity方法 5
            //第一阶段结束
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            //检查startActivity返回的结果
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
   
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

AMS到ApplicationThread阶段

4 5 6 ActivityManagerService的startActivity方法

    //对应图中5和6
    @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) {
   
        //7 进去
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                //多了一个UserId,用于多用户
                UserHandle.getCallingUserId());
    }

7 ActivityManagerService的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 bOptions, int userId) {
   
        //进去
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                //多了一个true
                true /*validateIncomingUser*/);
    }

再点进去

    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,
            boolean validateIncomingUser) {
   
        enforceNotIsolatedCaller("startActivity");

        userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

        // TODO: Switch to user app stacks here.
        //建造者模式
        //obtainStarter通过工厂模式获取ActivityStarter对象
        return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                //进去
                .execute();

    }

ActivityStarter的execute方法

    int execute() {
   
        try {
   
            // TODO(b/64750076): Look into passing request directly to these methods to allow
            // for transactional diffs and preprocessing.
            if (mRequest.mayWait) {
   
                //8 进去
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                        mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                        mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                        mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            } else {
   
                return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                        mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
                        mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                        mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
                        mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
                        mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                        mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                        mRequest.outActivity, mRequest.inTask, mRequest.reason,
                        mRequest.allowPendingRemoteAnimationRegistryLookup);
            }
        } finally {
   
            onExecutionComplete();
        }
    }

8 ActivityStarter的startActivityMayWait方法

 private 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, SafeActivityOptions options, boolean ignoreTargetSecurity,
            int userId, TaskRecord inTask, String reason,
            boolean allowPendingRemoteAnimationRegistryLookup) {
   
            
        省略代码...
        
        // Save a copy in case ephemeral needs it
        //复制新的Intent对象,
        //后续要对Intent进行修改,复制一份使原有Intent不受影响
        final Intent ephemeralIntent = new Intent(intent);
        // Don't modify the client's object!
        intent = new Intent(intent);
        
        省略代码...
        
        // Collect information about the target of the Intent.
        //收集Intent,看有哪些Activity可以处理这个action
        //比如想打开pdf文件,而手机上安装和WPS和其他PDF阅读器,这行代码会收集可以打开pdf文件
        //的Activity,然后弹出对话框让用户选一个
        ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

        省略代码...

        final ActivityRecord[] outRecord = new ActivityRecord[1];
        //9 进去
        int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                    ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
                    allowPendingRemoteAnimationRegistryLookup);

        Binder.restoreCallingIdentity(origId);

        省略代码...

    }

9 ActivityStarter的startActivity方法

  private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, TaskRecord inTask, String reason,
            boolean allowPendingRemoteAnimationRegistryLookup) {
   

        省略代码...
        
        //10 进去
        mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                inTask, allowPendingRemoteAnimationRegistryLookup);

        省略代码...
    }

10 ActivityStarter的startActivity方法

    private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            SafeActivityOptions options,
            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
            TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
   
        
        省略代码...
        
        //获取我们应用的进程描述类,ProcessRecord对象,获取原理是先获取所有进程
        //然后用我们的caller和ProcessRecord下的thread对象做对比,如果是同一个便可以作为返回结果了
        ProcessRecord callerApp = null;
        if (caller != null) {
   
            callerApp = mService.getRecordForAppLocked(caller);
            if (callerApp != null) {
   
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } else {
   
                Slog.w(TAG, "Unable to find app for caller " + caller
                        + " (pid=" + callingPid + ") when starting: "
                        + intent.toString());
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }
        //又一次获取userId,如果单用户,还是之前那一个userId
        final int userId = aInfo != null && aInfo.applicationInfo != null
                ? UserHandle.getUserId
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值