彻底理解startActivity的启动过程这一篇就够了

本文基于Android 6.0源码,详述ActivityManagerService如何处理startActivity请求,涉及ActivityManagerService、ActivityStack、ApplicationThread等多个组件,揭示从应用进程到系统进程再到目标进程的启动流程,包括Intent解析、ActivityRecord创建、Task分配、进程管理等关键步骤。
摘要由CSDN通过智能技术生成

 

    基于Android 6.0的源码剖析, 分析android Activity启动流程,相关源码:

    frameworks/base/services/core/java/com/android/server/am/
      - ActivityManagerService.java
      - ActivityStackSupervisor.java
      - ActivityStack.java
      - ActivityRecord.java
      - ProcessRecord.java
     
    frameworks/base/core/java/android/app/
      - IActivityManager.java
      - ActivityManagerNative.java (内含AMP)
      - ActivityManager.java
      
      - IApplicationThread.java
      - ApplicationThreadNative.java (内含ATP)
      - ActivityThread.java (内含ApplicationThread)
      
      - ContextImpl.java

一. 概述

startActivity的整体流程与startService启动过程分析非常相近,但比Service启动更为复杂,多了stack/task以及UI的相关内容以及Activity的生命周期更为丰富。

Activity启动发起后,通过Binder最终交由system进程中的AMS来完成,则启动流程如下图:

接下来,从源码来说说每个过程。
二. 启动流程
2.1 Activity.startActivity

[-> Activity.java]

    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }
     
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            //[见小节2.2]
            startActivityForResult(intent, -1);
        }
    }

2.2 startActivityForResult

[-> Activity.java]

    public void startActivityForResult(Intent intent, int requestCode) {
        startActivityForResult(intent, requestCode, null);
    }
     
    public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
        if (mParent == null) {
            //[见小节2.3]
            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());
            }
            //此时requestCode =-1
            if (requestCode >= 0) {
                mStartedActivity = true;
            }
            cancelInputsAndStartExitTransition(options);
        } else {
            ...
        }
    }

execStartActivity()方法的参数:

    mAppThread: 数据类型为ApplicationThread,通过mMainThread.getApplicationThread()方法获取。
    mToken: 数据类型为IBinder.

2.3 execStartActivity

[-> Instrumentation.java]

    public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) {
     
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        ...
     
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    if (am.match(who, null, intent)) {
                        am.mHits++;
                        //当该monitor阻塞activity启动,则直接返回
                        if (am.isBlocking()) {
                            return requestCode >= 0 ? am.getResult() : null;
                        }
                        break;
                    }
                }
            }
        }
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess();
            //[见小节2.4]
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            //检查activity是否启动成功
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

关于 ActivityManagerNative.getDefault()返回的是ActivityManagerProxy对象. 此处startActivity()的共有10个参数, 下面说说每个参数传递AMP.startActivity()每一项的对应值:

    caller: 当前应用的ApplicationThread对象mAppThread;
    callingPackage: 调用当前ContextImpl.getBasePackageName(),获取当前Activity所在包名;
    intent: 这便是启动Activity时,传递过来的参数;
    resolvedType: 调用intent.resolveTypeIfNeeded而获取;
    resultTo: 来自于当前Activity.mToken
    resultWho: 来自于当前Activity.mEmbeddedID
    requestCode = -1;
    startFlags = 0;
    profilerInfo = null;
    options = null;

2.4 AMP.startActivity

[-> ActivityManagerNative.java :: ActivityManagerProxy]

    class ActivityManagerProxy implements IActivityManager {
        ...
        public int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();
            data.writeInterfaceToken(IActivityManager.descriptor);
            data.writeStrongBinder(caller != null ? caller.asBinder() : null);
            data.writeString(callingPackage);
            intent.writeToParcel(data, 0);
            data.writeString(resolvedType);
            data.writeStrongBinder(resultTo);
            data.writeString(resultWho);
            data.writeInt(requestCode);
            data.writeInt(startFlags);
            if (profilerInfo != null) {
                data.writeInt(1);
                profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
            } else {
                data.writeInt(0);
            }
            if (options != null) {
                data.writeInt(1);
                options.writeToParcel(data, 0);
            } else {
                data.writeInt(0);
            }
            //[见流程2.5]
            mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
            reply.readException();
            int result = reply.readInt();
            reply.recycle();
            data.recycle();
            return result;
        }
        ...
    }

AMP经过binder IPC,进入ActivityManagerNative(简称AMN)。接下来程序进入了system_servr进程,开始继续执行。
2.5 AMN.onTransact

[-> ActivityManagerNative.java]

    public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        switch (code) {
        case START_ACTIVITY_TRANSACTION:
        {
          data.enforceInterface(IActivityManager.descriptor);
          IBinder b = data.readStrongBinder();
          IApplicationThread app = ApplicationThreadNative.asInterface(b);
          String callingPackage = data.readString();
          Intent intent = Intent.CREATOR.createFromParcel(data);
          String resolvedType = data.readString();
          IBinder resultTo = data.readStrongBinder();
          String resultWho = data.readString();
          int requestCode = data.readInt();
          int startFlags = data.readInt();
          ProfilerInfo profilerInfo = data.readInt() != 0
                  ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
          Bundle options = data.readInt() != 0
                  ? Bundle.CREATOR.createFromParcel(data) : null;
          //[见流程2.6]
          int result = startActivity(app, callingPackage, intent, resolvedType,
                  resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
          reply.writeNoException();
          reply.writeInt(result);
          return true;
        }
        ...
        }    }

2.6 AMS.startActivity

[-> ActivityManagerService.java]

    public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, options,
            UserHandle.getCallingUserId());
    }
     
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                false, ALLOW_FULL_ONLY, "startActivity", null);
        //[见小节2.7]
        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, options, false, userId, null, null);
    }

此处mStackSupervisor的数据类型为ActivityStackSupervisor

2.7 ASS.startActivityMayWait

当程序运行到这里时, ASS.startActivityMayWait的各个参数取值如下:

    caller = ApplicationThreadProxy, 用于跟调用者进程ApplicationThread进行通信的binder代理类.
    callingUid = -1;
    callingPackage = ContextImpl.getBasePackageName(),获取调用者Activity所在包名
    intent: 这是启动Activity时传递过来的参数;
    resolvedType = intent.resolveTypeIfNeeded
    voiceSession = null;
    voiceInteractor = null;
    resultTo = Activity.mToken, 其中Activity是指调用者所在Activity, mToken对象保存自己所处的ActivityRecord信息
    resultWho = Activity.mEmbeddedID, 其中Activity是指调用者所在Activity
    requestCode = -1;
    startFlags = 0;
    profilerInfo = null;
    outResult = null;
    config = null;
    options = null;
    ignoreTargetSecurity = false;
    userId = AMS.handleIncomingUser, 当调用者userId跟当前处于同一个userId,则直接返回该userId;当不相等时则根据调用者userId来决定是否需要将callingUserId转换为mCurrentUserId.
    iContainer = null;
    inTask = null;

再来看看这个方法的源码:

[-> ActivityStackSupervisor.java]

    ​
    ​
    ​
    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 config, Bundle options, boolean ignoreTargetSecurity,
    int userId, IActivityContainer iContainer, TaskRecord inTask) {
        ...
        boolean componentSpecified = intent.getComponent() != null;
        //创建新的Intent对象,即便intent被修改也不受影响
        intent = new Intent(intent);
     
        //收集Intent所指向的Activity信息, 当存在多个可供选择的Activity,则直接向用户弹出resolveActivity [见2.7.1]
        ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
     
        ActivityContainer container = (ActivityContainer)iContainer;
        synchronized (mService) {
            if (container != null && container.mParentActivity != null &&
                    container.mParentActivity.state != RESUMED) {
                ... //不进入该分支, container == nul
            }
     
            final int realCallingPid = Binder.getCallingPid();
            final int realCallingUid = Binder.getCallingUid();
            int callingPid;
            if (callingUid >= 0) {
                callingPid = -1;
            } else if (caller == null) {
                callingPid = realCallingPid;
                callingUid = realCallingUid;
            } else {
                callingPid = callingUid = -1;
            }
     
            final ActivityStack stack;
            if (container == null || container.mStack.isOnHomeDisplay()) {
                stack = mFocusedStack; // 进入该分支
            } else {
                stack = container.mStack;
            }
     
            //此时mConfigWillChange = false
            stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0;
     
            final long origId = Binder.clearCallingIdentity();
     
            if (aInfo != null &&
                    (aInfo.applicationInfo.privateFlags
                            &ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
                // heavy-weight进程处理流程, 一般情况下不进入该分支
                if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
                    ...
                }
            }
     
            //[见流程2.8]
            int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                    voiceSession, voiceInteractor, resultTo, result

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值