Android Activity的启动流程(Android-10)

前言

在Android开发中,我们经常会用到startActivity(Intent)方法,但是你知道startActivity(Intent)后Activity的启动流程吗?今天就专门讲一下最基础的startActivity(Intent)看一下Activity的启动流程,同时由于Launcher的启动后续和这里基本类似,就记录在一起。注意本章都是基于Android-10来讲解的。

客户端startActivity启动流程

startActivity启动流程本质上就是:向ActivityManagerService发送启动请求。由于发送端基本是在当前用户App进程或者Launcher进程(从桌面启动新的App)。除了SystemServer启动Launcher外,都需要借助AIDL发送请求。

1:客户端启动流程

startActivity方法在Activity,startActivity有两个重载方法,最终都会调用startActivityForResult(Intent,int, Bundle)方法,代码如下:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
     if (mParent == null) {
        //...
        Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
        //...
     } else {

        if (options != null) {
             mParent.startActivityFromChild(this, intent, requestCode, options);
         } else {
             mParent.startActivityFromChild(this, intent, requestCode);
         }
     }
}

其中mParent是当前Activity的父Activity,目前我只能想到TabActivity场景下才会存在一个Activity中包含Activity的情况,虽然它已经被Fragment替代了。所以基本上代码都是走mParent == null的流程,调用Instrumentation的execStartActivity方法。当然,在startActivityFromChild 方法里也是如此(不难发现,该方法已经被废弃了),源码如下,俩个重载的方法均已经废弃:

    /** @deprecated */
    @Deprecated
    public void startActivityFromChild(@NonNull Activity child, Intent intent, int requestCode) {
        throw new RuntimeException("Stub!");
    }

    /** @deprecated */
    @Deprecated
    public void startActivityFromChild(@NonNull Activity child, Intent intent, int requestCode, @Nullable Bundle options) {
        throw new RuntimeException("Stub!");
    }

我们继续看execStartActivity方法的关键代码:

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
     //...
     try {
            intent.migrateExtraStreamToClipData(who);
            intent.prepareToLeaveProcess(who);
            	//备注一
            int result = ActivityTaskManager.getService().startActivity(whoThread,
                    who.getBasePackageName(), who.getAttributionTag(), 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;
}

其中,备注一处就是获取ActivityTaskManager服务并向其发送请求。备注二处会根据备注一处的返回结果检查Activity的启动状态,源码如下:

public static void checkStartActivityResult(int res, Object intent) {
        if (!ActivityManager.isStartResultFatalError(res)) {
            //如果没法发生启动错误,直接返回
            return;
        }

        switch (res) {
            case ActivityManager.START_INTENT_NOT_RESOLVED:
            case ActivityManager.START_CLASS_NOT_FOUND:
                if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
                    throw new ActivityNotFoundException(
                            "Unable to find explicit activity class "
                            + ((Intent)intent).getComponent().toShortString()
                            + "; have you declared this activity in your AndroidManifest.xml?");
                throw new ActivityNotFoundException(
                        "No Activity found to handle " + intent);
            case ActivityManager.START_PERMISSION_DENIED:
                throw new SecurityException("Not allowed to start activity "
                        + intent);
            case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
                throw new AndroidRuntimeException(
                        "FORWARD_RESULT_FLAG used while also requesting a result");
            //...
            default:
                throw new AndroidRuntimeException("Unknown error code "
                        + res + " when starting " + intent);
        }
}

可以看到checkStartActivityResult在Activity里会根据启动失败的原因并抛出异常:注意里面的case ActivityManager.START_CLASS_NOT_FOUND,你一定知道如果没有在AndroidManifest.xml文件里声明Activity,就会抛出异常。没错,就是根据AMS返回的错误码,在这里抛出的异常。

当然,检查并不是在这里。checkStartActivityResult不负责任何启动Activity以及检查配置文件的工作,它之负责根据AMS的返回结果抛出异常。接下来回到备注一,看一下重点工作 ActivityTaskManager的getService方法。

public static IActivityTaskManager getService() {
        return IActivityTaskManagerSingleton.get();
    }

@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
            new Singleton<IActivityTaskManager>() {
                @Override
                protected IActivityTaskManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                    return IActivityTaskManager.Stub.asInterface(b);
            }
     };

代码比较简单,一个匿名内部类IActivityTaskManagerSingleton,里面的create 方法返回了一个IActivityTaskManager对象,根据方法里的内容就能猜出它个AIDL,该AIDL文件可在IActivityTaskManager源码里查看。

接着看一个ActivityTaskManagerSingleton.get()方法,get方法在它的父类Singleton中定义:

public abstract class Singleton<T> {

    @UnsupportedAppUsage
    public Singleton() {
    }

    @UnsupportedAppUsage
    private T mInstance;

    protected abstract T create();

    @UnsupportedAppUsage
    public final T get() {
        synchronized (this) {
            if (mInstance == null) {
                mInstance = create();
            }
            return mInstance;
        }
    }
}

很简单的代码,一个懒汉式单例。如果实例为空,就调用create()方法,也就是上文中匿名内部类中复写的方法。到这里,一切就明了了:这里就准备开始跨进程通讯了ActivityTaskManager.getService方法就是客户端(发起创建Activity的当前App进程)向服务端(AMS)获取获取Binder对象用于跨进程通讯。而关键代码就是IActivityTaskManager.Stub.asInterface(b)。(注意IActivityTaskManager只是个AIDL文件,是为了自动生成代码的工具,更多关于AIDL的知识请看Android里的多进程和跨进程通讯方式)

接下来看final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);,看它是如何获得Binder实例的:

private static Map<String, IBinder> sCache = new ArrayMap<String, IBinder>();

public static IBinder getService(String name) {
    try {
            IBinder service = sCache.get(name);
            if (service != null) {
            // 有缓存,直接从缓存获取
                return service;
            } else {
            // 没有缓存重新通过ServiceManager获取
                return Binder.allowBlocking(rawGetService(name));
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
}

上面是ServiceManager.getService方法的代码。ServiceManager是Android用来关系系统服务的,Android系统给我们提供了很多服务,每一个服务都有一个对应的类(AMS,WMS等),开发过程中我们就是通过这些类来获得我们所需要的服务。而ServiceManager则通过一个ArrayMap来缓存这些服务。这里也是如此:getService(Context.ACTIVITY_TASK_SERVICE)不难看出是要获得ActivityTaskManagerService的。看一下ActivityTaskManagerService:
Android Activity的启动流程(Android-10)_第1张图片

它继承了IActivityTaskManager.Stub!!!就和上文中我们的AIDL文件对应上了。可以肯定ActivityTaskManagerService就是这次AIDL跨进程通讯的服务端了。

为了以防万一,我们还是要追踪一下ActivityTaskManagerService是如何添加到ServiceManager中的。这时,我们就要了解一下Android系统的启动流程了:ActivityTaskManagerService作为系统服务,是在SystemServer中被启动的:

 ActivityTaskManagerService atm = mSystemServiceManager.startService(
                ActivityTaskManagerService.Lifecycle.class).getService();
mActivityManagerService = ActivityManagerService.Lifecycle.startService(
                mSystemServiceManager, atm);

其中SystemServiceManager.startService是通过反射创建Service的:

public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            //..
            final T service;
            try {
            		//通过反射创建实例
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            } 
            //...
		//启动服务
            startService(service);
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
}

代码很简单,就是通过反射创建服务并启动。我们接着看启动服务的startService(service);方法:

public void startService(@NonNull final SystemService service) {
        //..
        try {
            service.onStart();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + service.getClass().getName()
                    + ": onStart threw an exception", ex);
        }
       
}

这里可以看出,明明我们创建的是ActivityTaskManagerServiceLifecycle,但是上面这段代码却是接收一个SystemService并调用它的onStart方法?原因只有一个,ActivityTaskManagerServiceLifecycle是SystemService的子类:

public static final class Lifecycle extends SystemService {
        private final ActivityTaskManagerService mService;

        public Lifecycle(Context context) {
            super(context);
            mService = new ActivityTaskManagerService(context);
        }

        @Override
        public void onStart() {
            publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
            mService.start();
        }
        //...
}

看一下源码也确实如此,那么紧接着看SystemService在Lifecycle中的实现中的一行代码:publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);。这里有出现了Context.ACTIVITY_TASK_SERVICE。就是在这里将ActivityTaskManagerService添加到ServiceManager中的。查看源码可发现SystemService有多个publishBinderService重载,并最终都调用了:

protected final void publishBinderService(String name, IBinder service,
            boolean allowIsolated, int dumpPriority) {
        ServiceManager.addService(name, service, allowIsolated, dumpPriority);
    }

没错,这里就调用了ServiceManager.addService方法了。最终调用方法在ServiceManager中:



public static void addService(String name, IBinder service, boolean allowIsolated,
            int dumpPriority) {
        try {
            getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
}

private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }

        // Find the service manager
        sServiceManager = ServiceManagerNative
                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
        return sServiceManager;
}

至此,服务的获取也明确了,ActivityTaskManagerService就是在系统启动时创建的。

2:服务端接收请求流程

接下来,就是继续看startActivity方法了,客户端Instrumentation调用,服务端ActivityTaskManagerService响应。ActivityTaskManagerService中有多个startActivity重载方法。经过不断调用,最终会调用startActivityAsUser方法:

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("startActivityAsUser");

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

        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                .execute(); //启动

    }

注意看ActivityStartController. obtainStarter方法!其中,最后的execute最终是执行的ActivityStarter的execute代码:

 /**
     * Starts an activity based on the request parameters provided earlier.
     * @return The starter result.
     */
    int execute() {
        try {
            // TODO(b/64750076): Look into passing request directly to these methods to allow
            // for transactional diffs and preprocessing.
            if (mRequest.mayWait) {
                return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                        mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
                        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,
                        mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
            } 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,
                        mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
            }
        } finally {
            onExecutionComplete();
        }
    }

其中,startActivity有三个的重载方法,经过不断的调用,最后会调用:startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity, boolean restrictedBgActivity) 方法:

 private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity, boolean restrictedBgActivity) {
     try {
         mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
     } 
 }

大致的流程图如下:
Android Activity的启动流程(Android-10)_第2张图片

但是,到了Launcher启动Activity时变终止了,最终在这里合流。

public class ActivityStartController {
     .... 
     ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }
}

所以,整个客户端的请求和处理流程大致如下:

接下来,就要开始创建了。

服务端处理流程

我们一步步分析看服务端的处理流程。

1:检验、初始化等基础工作

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,
            PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
        //...
        //创建错误码,默认是成功的
        int err = ActivityManager.START_SUCCESS;
        // Pull the optional Ephemeral Installer-only bundle out of the options early.
        final Bundle verificationBundle
                = options != null ? options.popAppVerificationBundle() : null;

        //..
        final int userId = aInfo != null && aInfo.applicationInfo != null
                ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;

        //..            
        final int launchFlags = intent.getFlags();

        //..
        //开始处理错误
        //找不到可以处理给定Intent的类
        if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
            err = ActivityManager.START_INTENT_NOT_RESOLVED;
        }

        //找不到Intent中指定的Ativity类,就是对应我们上文中没有在配置文件里配置Activity
        if (err == ActivityManager.START_SUCCESS && aInfo == null) {
            err = ActivityManager.START_CLASS_NOT_FOUND;
        }

        //..

        final ActivityStack resultStack = resultRecord == null
                ? null : resultRecord.getActivityStack();

        //如果错误码被改变,不为成功,则返回给客户端启动失败        
        if (err != START_SUCCESS) {
            if (resultRecord != null) {
                resultStack.sendActivityResultLocked(
                        -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
            }
            SafeActivityOptions.abort(options);
            return err;
        }

        // 检查启动activity的权限
        boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
                requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
                inTask != null, callerApp, resultRecord, resultStack);
        abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                callingPid, resolvedType, aInfo.applicationInfo);
        abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
                callingPackage);

        // 检查是否允许后台启动activity
        if (!abort) {
            try {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        "shouldAbortBackgroundActivityStart");
                restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid,
                        callingPid, callingPackage, realCallingUid, realCallingPid, callerApp,
                        originatingPendingIntent, allowBackgroundActivityStart, intent);
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
        }

        //..

        // 判断如果有权限需要哦用户审阅才能运行Activity
        if (aInfo != null) {
            // 获取此包使用的某些权限是否需要用户审核才能运行任何应用程序组件
            if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
                    aInfo.packageName, userId)) {
                IIntentSender target = mService.getIntentSenderLocked(
                        ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
                        callingUid, userId, null, null, 0, new Intent[]{intent},
                        new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
                                | PendingIntent.FLAG_ONE_SHOT, null);

                Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);

                //..
            }
        }

    
        //创建ActivityRecord
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, checkedOptions, sourceRecord);
        //..
        //创建ActivityStack
        final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
        //..
        // 进入启动activity的流程(
        final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
        mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outActivity[0]);
        return res;
    }

该方法主要做了一下两件事:

  1. 执行初步的配置、权限等基本的检查工作;
  2. 创建ActivityRecord对象,并获取ActivityStack对象。

第一步的检查包括Intent的检查,包括里面Activity的类型检查。还要进行权限,是否允许后台启动等检查。第二部主要是创建Activity启动的辅助类,ActivityRecord负责存储一些关于Activity组件的相关信息。是应用层Activity组件在AMS中的代表,每一个在应用中启动的Activity,在AMS中都有一个ActivityRecord实例来与之对应。ActivityRecord则由TaskRecord通过一个ArrayList管理,而ActivityStack则用来管理TaskRecord。它们之间的关系大致如下图片所示:

Android Activity的启动流程(Android-10)_第3张图片
紧接着又会调用startActivity的重载方法:

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity, boolean restrictedBgActivity) {
        int result = START_CANCELED;
        final ActivityStack startedActivityStack;
        try {
            //准备启动,暂停页面布局绘制
            mService.mWindowManager.deferSurfaceLayout();
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);
        } finally {
            final ActivityStack currentStack = r.getActivityStack();
            startedActivityStack = currentStack != null ? currentStack : mTargetStack;

            if (ActivityManager.isStartResultSuccessful(result)) {
                if (startedActivityStack != null) {
                    //处理Activity信息,并确保显示,更新方向等配置信息
                    final ActivityRecord currentTop =
                            startedActivityStack.topRunningActivityLocked();
                    if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
                        mRootActivityContainer.ensureVisibilityAndConfig(
                                currentTop, currentTop.getDisplayId(),
                                true /* markFrozenIfConfigChanged */, false /* deferResume */);
                    }
                }
            } else {
                //如果失败了,请取消Activity与栈的关联。
                //让Activity处于不完整状态可能会导致问题,
                //例如在没有窗口容器的情况下执行操作。
                final ActivityStack stack = mStartActivity.getActivityStack();
                if (stack != null) {
                    stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
                            null /* intentResultData */, "startActivity", true /* oomAdj */);
                }

                //执行失败的逻辑,移除堆信息
                if (startedActivityStack != null && startedActivityStack.isAttached()
                        && startedActivityStack.numActivities() == 0
                        && !startedActivityStack.isActivityTypeHome()) {
                    startedActivityStack.remove();
                }
            }
            //重新开始绘制
            mService.mWindowManager.continueSurfaceLayout();
        }

        postStartActivityProcessing(r, result, startedActivityStack);

        return result;
    }

代码的详细解读写在了注释里面。这里关键的步骤就是调用startActivityUnchecked。

2:任务栈的创建和获取

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity, boolean restrictedBgActivity) {
        //初始化Activity配置    
        //此处会直接将mDoResume设置为true
        //在该方法末尾会用到
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor, restrictedBgActivity);

        final int preferredWindowingMode = mLaunchParams.mWindowingMode;
        //计算Activity的Flag,也就是mLaunchFlags
        computeLaunchingTaskFlags();
        computeSourceStack();
        
        //将mLaunchFlags设置给mIntent
        mIntent.setFlags(mLaunchFlags);

        //判断Activity是否可以放入到一个已经存在的任务栈
        //如果返回null则标识需要新的任务栈
        ActivityRecord reusedActivity = getReusableIntentActivity();

        //..

        //如果有可以复用的ActivityRecord
        if (reusedActivity != null) {
            //..
            //判断是否需要清空任务栈栈顶
            final boolean clearTopAndResetStandardLaunchMode =
                    (mLaunchFlags & (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED))
                            == (FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
                    && mLaunchMode == LAUNCH_MULTIPLE;

            //将ActivityRecord加入到TaskRecord
            if (mStartActivity.getTaskRecord() == null && !clearTopAndResetStandardLaunchMode) {
                mStartActivity.setTask(reusedActivity.getTaskRecord());
            }

           
            // 判断是否要清除TaskRecord
            if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                    || isDocumentLaunchesIntoExisting(mLaunchFlags)
                    || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK)) {
                //获取可复用的TaskRecord
                final TaskRecord task = reusedActivity.getTaskRecord();

                
                final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
                        mLaunchFlags);

                //重新进行赋值
                if (reusedActivity.getTaskRecord() == null) {
                    reusedActivity.setTask(task);
                }

                //..
            }

            mRootActivityContainer.sendPowerHintForLaunchStartIfNeeded
                    (false /* forceSend */, reusedActivity);
            //将被复用的Task防置到前台
            reusedActivity = setTargetStackAndMoveToFrontIfNeeded(reusedActivity);

            final ActivityRecord outResult =
                    outActivity != null && outActivity.length > 0 ? outActivity[0] : null;

            // When there is a reused activity and the current result is a trampoline activity,
            // set the reused activity as the result.
            if (outResult != null && (outResult.finishing || outResult.noDisplay)) {
                outActivity[0] = reusedActivity;
            }

            if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
                //START_FLAG_ONLY_IF_NEEDED:只需要使task放到前台,无需去启动,(eg. 从桌面点击图标恢复task的情况)。
                resumeTargetStackIfNeeded();
                return START_RETURN_INTENT_TO_CALLER;
            }

            if (reusedActivity != null) {
                setTaskFromIntentActivity(reusedActivity);

                if (!mAddingToTask && mReuseTask == null) {
                     //将Stack调用到前台
                    resumeTargetStackIfNeeded();
                    //..

                    return mMovedToFront ? START_TASK_TO_FRONT : START_DELIVERED_TO_TOP;
                }
            }
        }

        // ..

        // 接下来判断要启动的Activity和当前栈顶的是否一样
        //并且判断时序需要启动
        final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack();
        final ActivityRecord topFocused = topStack.getTopActivity();
        final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop);
        //判断是否需要启动Activity
        final boolean dontStart = top != null && mStartActivity.resultTo == null
                && top.mActivityComponent.equals(mStartActivity.mActivityComponent)
                && top.mUserId == mStartActivity.mUserId
                && top.attachedToProcess()
                && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
                || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
                && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);

        if (dontStart) {
            //无需重启,直接将当前activity显示到前台
            topStack.mLastPausedActivity = null;
            if (mDoResume) {
                mRootActivityContainer.resumeFocusedStacksTopActivities();
            }
            //..

            //返回启动结果,结束
            return START_DELIVERED_TO_TOP;
        }

        boolean newTask = false;
        final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
                ? mSourceRecord.getTaskRecord() : null;

        
        int result = START_SUCCESS;
        // 判断是否需要一个新的任务栈
        // 并分情况设置任务栈
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
        } else if (mSourceRecord != null) {
            result = setTaskFromSourceRecord();
        } else if (mInTask != null) {
            result = setTaskFromInTask();
        } else {
            result = setTaskToCurrentTopOrCreateNewTask();
        }
        //根据设置任务栈的返回值判断是否发生错误
        //如果发生了错误,那么就直接返回
        if (result != START_SUCCESS) {
            return result;
        }


        //..
        //这里我们只关注mDoResume为true的情况
        //因为在我们上文中startActivity方法中有如下调用:
        //final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
        //        true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);
        //其中的doResume,在该方法开头第一步,就会将mDoResume设置为true
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTaskRecord().topRunningActivityLocked();
            //如果当前任务栈没有获得焦点走这里
            //我们按照主流程会走else        
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                //..
            } else {
            
                if (mTargetStack.isFocusable()
                        && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                mRootActivityContainer.resumeFocusedStacksTopActivities(
                        mTargetStack, mStartActivity, mOptions);
            }
        } else if (mStartActivity != null) {
            //..
        }
        //..

        return START_SUCCESS;
    }

该方法代码量很大,关键的节点已经写在注释里面了。但是它的工作其实也很简单:主要就是准备好任务栈,并且将acticityRecord加入到TaskRecord中。而它的复杂支出就在于复用等一系列的判断和准备工作。

这里补充一下getReusableIntentActivity判断任务栈复用的关键代码:

 private ActivityRecord getReusableIntentActivity() {
        //android会尽量的将Activity放入到已经存在的任务栈中
        //尤其是使用了singleTask和singleInstance模式启动的Activity
        //而对于使用了FLAG_ACTIVITY_NEW_TASK也会尽量保持这种风格


        //以下集中情况才会允许插入到已经存在的任务栈里
        //standard启动模式而且intent且添加FLAG_ACTIVITY_NEW_TASK
        //使用singleTask和singleInstance启动的Activity
        boolean putIntoExistingTask = ((mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0 &&
                (mLaunchFlags & FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
                || isLaunchModeOneOf(LAUNCH_SINGLE_INSTANCE, LAUNCH_SINGLE_TASK);
        
        ActivityRecord intentActivity = null;
        if (mOptions != null && mOptions.getLaunchTaskId() != -1) {
            final TaskRecord task = mRootActivityContainer.anyTaskForId(mOptions.getLaunchTaskId());
            intentActivity = task != null ? task.getTopActivity() : null;
        } else if (putIntoExistingTask) {
            //..
            //省略复用的逻辑
        }

        //不能复用桌面Activity
        if (intentActivity != null
                && (mStartActivity.isActivityTypeHome() || intentActivity.isActivityTypeHome())
                && intentActivity.getDisplayId() != mPreferredDisplayId) {
            intentActivity = null;
        }

        return intentActivity;
    }

此时,任务栈已经准备好了。紧接着关注一下 mRootActivityContainer.resumeFocusedStacksTopActivities(mTargetStack, mStartActivity, mOptions);也就是RootActivityContainer.resumeFocusedStacksTopActivities方法:

boolean resumeFocusedStacksTopActivities(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

        //..
        boolean result = false;
        if (targetStack != null && (targetStack.isTopStackOnDisplay()
                || getTopDisplayFocusedStack() == targetStack)) {
            //如果Activity的目标栈正处于前台,那么直接调用方法
            //将ActivityRecord(target)放置到顶部
            result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }

        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            boolean resumedOnDisplay = false;
            final ActivityDisplay display = mActivityDisplays.get(displayNdx);
            //..

            //如果目标栈没有显示在屏幕上
            //则获取当前的ActivityStack,将ActivityRecord(target)放置到顶部
            if (!resumedOnDisplay) {
                final ActivityStack focusedStack = display.getFocusedStack();
                if (focusedStack != null) {
                    focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
                }
            }
        }

        return result;
    }

该段代码的目的就是为了让目标的Activity的表述ActivityRecord(target)放置在前台。当然,是通过ActivityStack.resumeTopActivityUncheckedLocked方法实现的。注意此时:放置我们要启动Activity的ActivityRecord的TaskRecord已经放在了前台,同时该ActivityRecord处在顶部。

3:通知ActivityThread创建

接下来关注关键的步骤,调用了resumeTopActivityInnerLocked方法:


private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        if (!mService.isBooting() && !mService.isBooted()) {
            // Not ready yet!
            return false;
        }
        //找到当前Task里最顶层的ActivityRecord
        //注意不是Activity的任务栈,而是ActivityTask
        //可以理解为是启动我们Activity(B)的Activity(A)
        //A可能是不同App的,比如Launcher,也可能是和B同一应用内
        //还记得上段代码的任务吗:放置我们要启动Activity的ActivityRecord的TaskRecord已经放在了前台
        //同时该ActivityRecord处在顶部。
        //这个next就是我们要启动的了

        ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
        //..

        //判断是否还有其他RESUMED状态的Activity
        if (mResumedActivity == next && next.isState(RESUMED)
                && display.allResumedActivitiesComplete()) {
            // Make sure we have executed any pending transitions, since there
            // should be nothing left to do at this point.
            executeAppTransition(options);
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Top activity resumed " + next);
            return false;
        }
        //..
        //重点一
        //调用ActivityDisplay.pauseBackStacks方法暂停后台Stack的Activity
        boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
        //暂停掉当前Stacks里处于活动状态的Activity
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            pausing |= startPausingLocked(userLeaving, false, next, false);
        }
        

        //判断要启动的Activity所要运行的进程是否已经存在
        if (next.attachedToProcess()) {

            try {
                //重点二
                //当Activity之前启动过,直接resume
                final ClientTransaction transaction =
                        ClientTransaction.obtain(next.app.getThread(), next.appToken);
               //..
                mService.getLifecycleManager().scheduleTransaction(transaction);

                if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed "
                        + next);
            } catch (Exception e) {
            	   // Whoops, need to restart this activity!
               //..
               //重点三
               mStackSupervisor.startSpecificActivityLocked(next, true, false);
            }

            //.. 
        } else {
            //进程没有运行,走启动进程的流程
            
            //..
		//重点四
            //创建进程的的逻辑就不展开了,创建完成之后之后最终还是会走后续的流程
            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }

        return true;
    }

代码注释比较详细了,这里解读一下关键点:

  1. 重点一:暂停掉处在前台的Activity,该步骤最终是通过startPausingLocked方法实现的,在这里调用了当前正在显示的Activity的onPause方法。
  2. 重点二:如果之前Activity启动过,直接resume,否则的话抛出异常,进入重点三
  3. 重点三:向ActivityThread发送创建Activity的请求。
  4. 重点四:如果Activity所要运行的线程还未创建,那么就会请求Zygote创建进程(创建过程就不展开说了)。而在进程创建完之后。Zygote会通过Binder通知ATMS(ActivityTaskManagerService),紧接着又会通过类似重点二的方式请求ActivityThread创建。

接着,我们看看是如何通知ActivityThread创建Activity的。分析重点三处的代码,它会通过ActivityStackSupervisor.startSpecificActivityLocked调用ActivityStackSupervisor.realStartActivityLocked方法:

boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {

        //..
            try {
                //..

                // 创建启动Activity的任务
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);

                final DisplayContent dc = r.getDisplay().mDisplayContent;
                // 非常重要:添加 LaunchActivityItem callback(备注一)
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.icicle, r.persistentState, results, newIntents,
                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                                r.assistToken));

                //..
                // 执行启动Activity的任务
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);

                //
            } //..

        return true;
    }

请记住备注一,这里添加了个LaunchActivityItem作为CallBack,它很重要。但是在讲解它之前,我们首先看ClientTransaction.obtain方法:

public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
        ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
        if (instance == null) {
            instance = new ClientTransaction();
        }
        instance.mClient = client;
        instance.mActivityToken = activityToken;

        return instance;
    }

代码很简单,就是初始化ClientTransaction,关键点在于mClient成员变量。它是一个IApplicationThread类型的,没错,它是AIDL。而它的具体实现在实现是ActivityThread.ApplicationThread,是ActivityThread的一个内部类。紧接着看mService.getLifecycleManager().scheduleTransaction(transaction);,这段代码调用了ClientLifecycleManager.scheduleTransaction:

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
	  //..
        transaction.schedule();
        //..
    }

紧接着调用ClientTransaction.schedule方法

public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

而这个mClient,就是我们的AIDL客户端(AMS)。使用它向我们的服务端(ActivityThread)发送请求:它实现就在ActivityThread$ApplicationThread中。

ActivityThread接受请求开始创建

接下来就是ActivityThread处理请求了:

@Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }

由于 ActivityThread继承自ClientTransactionHandler,所以scheduleTransaction会调用ClientTransactionHandler. scheduleTransaction方法:

void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

而sendMessage定义在ActivityThread中,它有多个重载方法,最终会执行:

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) {
            Slog.v(TAG,
                    "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
        }
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }

很明显这是一个Handler,接着看mH的具体实现:

public void handleMessage(Message msg) {
    //..
    switch (msg.what) {
        //..
        //执行生命周期的调度工作
         case EXECUTE_TRANSACTION:
            final ClientTransaction transaction = (ClientTransaction) msg.obj;
            mTransactionExecutor.execute(transaction);
            //..
            break;
        //..
    }

    //..
}

很明显,AMS使用Binder请求ActivityThread创建Activity,然后ActivityThread通过Handler机制向TransactionExecutor发送创建的请求。

紧接着看TransactionExecutor的execute方法:

public void execute(ClientTransaction transaction) {
        //..
        executeCallbacks(transaction);

        //..
}

关键方法就是调用了executeCallbacks:

    public void executeCallbacks(ClientTransaction transaction) {
    	  final List callbacks = transaction.getCallbacks();
        //..
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            //..

            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            //..
        }
    }

没错,在这里就用到了CallBack了,这里面必定有刚刚备注一里提到的LaunchActivityItem。我们直接看它的execute方法:

 public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        //..
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

调用了ClientTransactionHandler的handleLaunchActivity方法。还记得上文说的ActivityThread继承自ClientTransactionHandler。其实这个ClientTransactionHandler就可以认为是ActivityThread,其中handleLaunchActivity的实现如下:

public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
      
        final Activity a = performLaunchActivity(r, customIntent);

}

只留下关键代码,调用了performLaunchActivity方法:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ActivityInfo aInfo = r.activityInfo;
        //..
        //创建上下文环境
        ContextImpl appContext = createBaseContextForActivity(r);
        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);
            }
        }

        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            //..

            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);

            
                //设置主题
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                //重点三:
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                //..
            }
           //..

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }

最最最重要的来了,我们关注代码注释里的几点: 重点一:通过反射创建Activity; 重点二:调用了Activity.attach()方法; 重点三:通过Instrumentation对象执行Activity的onCreate()方法。

到这里,Activity就算是创建完成了。

总结

到这里,Activity的创建就完成了。放一个极简版序列图:

Android Activity的启动流程(Android-10)_第4张图片
其中Ams为ActivityManagerService,Android最近一些较新的版本为了解决ActivityManagerService臃肿的问题引入了ActivityTaskManagerService来分担Ams工作,就是图中的Atms。

Activity的关系大致如下图:

如上图所示,除了启动Activity的进程和Activity运行的进程可能为同一进程,它们互为不同进程。当要创建一个Activity时:

  1. 如果Activity所依赖的进程已经存在,那么流程为:Step:1->2。如果启动进程和运行进程是一个,那么该过程只涉及到两个进程(启动进程和AMS进程),否则就是三个(启动进程、运行进程和AMS进程)
  2. 如果Activity所依赖的进程不存在,那么流程为:Step:1->3->4->2。

本文只讲述了请求创建的流程,其中省略了很多其他操作。包括,Activity生命周期的调用(都是由Instrumentation对象来调用的)、进程的创建、activity的attach等其他重要操作。相关知识可以由于能力有限,大家可自行查看Android源码自行了解。

最后推荐一些比较好的博客,供参考学习:

  1. ActivityRecord、TaskRecord、ActivityStack以及Activity启动模式详解
  2. 四大组件之ActivityRecord
  3. 深入理解ActivityRecord、TaskRecord、ActivityStack的作用及关系
  4. framework之Activity启动流程
  5. Android启动流程源码解析

你可能感兴趣的:(Android,Kotlin,Java,java,kotlin,android)