Android | Activity 启动流程分析

Android Activity启动流程○ 从点击屏幕上的应用icon,到该应用展示第一个可视界面,这个过程中,Android系统究竟做了什么操作?又涉及到哪些进程? 1.根Activity启动过程 ①从Launcher到AMS 当点击屏幕上的应用icon时,Laucher发送启动应用的请求给AMS,因为Launcher是在Launcher进程,而AMS是在SystemServer进程。因此,实现这个请求,本质上是在实现一个跨进程通信的功能。在安卓领域实现跨进程通信的技术有多种,像是Broadcast、ContentProvinder等。在系. 阅读详情
AI摘要

本文基于Android 12版本源码,分析应用内启动Activity的流程。从Activity到ATMS,再到ActivityThread,详细阐述了各阶段的操作,包括权限检查、任务栈管理、进程创建等,最后总结了完整的启动流程,还提供了Android进阶学习指南。

前言

Activity 类是 android 应用的关键组件,在日常开发中,绝对少不了组件。既然用了这么久,你知道他的启动流程🐴?作为一个应用层开发者,大多数人可能觉得学习这些对日常开发可能没有太大帮助。但是多了解一下 framework 的代码还是很有必要的,了解系统组件机制,对于一些问题我们也能快速的定位找到问题的所在点,并且在面试的时候也是一个加分项。

本文基于 Android 12 版本源码,从 startActivity 作为切入点,对整个启动流程进行分析。

Activity 启动方式

启动一个 Activity,通常有两种情况,一种是在应用内部启动 Activity,另一种是 Launcher 启动。

  • 应用内启动 通过 startActivity 来启动 Activity
  • Launcher 进程启动 Launcher 就是我们桌面程序,当系统开机后, Launcher 也随之被启动,然后将已经安装的 app 显示在桌面上,等到点击某一个 app 的时候就会 fock 一个新的进程,然后启动 Activity

这篇文章主要来看一下应用内启动 Activity 是一个怎样的流程

一,Activity -> ATMS

众所周知,一般情况下Activity 的启动方式有下面种:

  • startActivity(Intent intent):直接启动一个 Activity
  • startActivityForResult(Intent intent, int requestCode):带返回值的启动方式,这种启动方式已经被官方所废弃,取而代之的是 registerForActivityResult(contract, mActivityResultRegistry, callback)

我们从 startActivity 来一步步往下看:

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 {
        startActivityForResult(intent, -1);
    }
}
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) {
        ......
        //execStartActivity
        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());
        }
        ......
    } else {
        if (options != null) {
            //这里最终也是调用 execStartActivity 方法
            mParent.startActivityFromChild(this, intent, requestCode, options);
        } else {
            mParent.startActivityFromChild(this, intent, requestCode);
        }
    }
}

上面代码中,调用了 execStartActivity 方法,该方法会返回一个启动结果。最下面的的 startActivityFromChild 方法最终也是调用的 execStartActivity。

我们先看一下该方法的参数:

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
}

Context who :传入的是 this,用来启动 Activity 的对象

Ibinder contextThread:Binder 对象,具有跨进程通信的能力,传入的是 mMainThread.getApplicationThread()

public ApplicationThread getApplicationThread(){
    return mAppThread;
}
final ApplicationThread mAppThread = new ApplicationThread();

private class ApplicationThread extends IApplicationThread.Stub {
    .....
}

ApplicationThread 是 Activitythread 的内部类,就是通过 AIDL 创建的一个远程服务的接口,用来与服务端进行交互,该对象会被传入到 AMS 中,在 AMS 中回保存他的 client(客户端),这样 AMS 就可以与应用进程进行通信了

IBinder token:Binder 对象,指向了服务端一个 ActivityRecord 对象

Activity target:当前的 Activity

Intent intent, int requestCode, Bundle options :Intent 对象,请求码和参数。

下面我们来看一下 execStartActivity 方法:

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    //应用端 AIDL 实现类
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    .......
    try {
        intent.migrateExtraStreamToClipData(who);
        intent.prepareToLeaveProcess(who);
        //通过 Binder 调用 ATMS 启动 Activity
        int result = ActivityTaskManager.getService().startActivity(whoThread,
                who.getOpPackageName(), 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;
}
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);
            }
        };

我们可以用一张图来表示上述的流程:

image-20221221164643149

image-20221221164643149

上面代码中通过 getService 获取到 Binder 对象,然后将 Binder 转成 AIDL 接口所属的类型,接着就可以调用 AIDL 中的方法与服务端进行通信了。

接着调用 ATMS 中的 startActivity() 方法发起启动 Activity 请求,获得启动结果 result。在调用 checkStartActivityResult 方法,传入 result,来判断能否启动 Activity,不能启动就会抛出异常,例如 activity 未在 manifest 中声明等。

二 、ATMS

通过上面的代码可以看出已经调用到了系统的 ATMS 当中,我们来看一下具体的流程

#ActivityTaskManagerService.java
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
        String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
        String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
        Bundle bOptions) {
    return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
            resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}
#ActivityTaskManagerService.java
public int startActivityAsUser(IApplicationThread caller, String callingPackage,
        String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
        String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
        Bundle bOptions, int userId) {
    return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
            resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
            true /*validateIncomingUser*/);
}
#ActivityTaskManagerService.java
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
        @Nullable String callingFeatureId, Intent intent, String resolvedType,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
    //检查调用者权限
    userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    // TODO: Switch to user app stacks here.
    return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setCallingFeatureId(callingFeatureId)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setUserId(userId)
            .execute();
}

上面代码最终调用到了 startActivityAsUser 方法,在内部将所有点的参数都交给了 ActivityStarter ,该类包含了启动的所有逻辑,比如 Intent 解析以及任务栈等。

接着调用了obtainStarter ,该方法通过工厂模式创建了 ActivityStarter 对象,如下所示:

#ActivityStarter.java
static class DefaultFactory implements Factory {
    /**
     * ActivitySatrter 最大数量
     */
    private final int MAX_STARTER_COUNT = 3;
    ......
        //同步池
    private SynchronizedPool<ActivityStarter> mStarterPool =
            new SynchronizedPool<>(MAX_STARTER_COUNT);

    DefaultFactory(ActivityTaskManagerService service,
            ActivityTaskSupervisor supervisor, ActivityStartInterceptor interceptor) {
        mService = service;
        mSupervisor = supervisor;
        mInterceptor = interceptor;
    }

    @Override
    public void setController(ActivityStartController controller) {
        mController = controller;
    }

    @Override
    public ActivityStarter obtain() {
        //从同步池中获取 ActivityStarter 对象
        ActivityStarter starter = mStarterPool.acquire();
        if (starter == null) {
            if (mService.mRootWindowContainer == null) {
                throw new IllegalStateException("Too early to start activity.");
            }
            starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
        }
        return starter;
    }

    @Override
    public void recycle(ActivityStarter starter) {
        starter.reset(true /* clearRequest*/);
        mStarterPool.release(starter);
    }
}

可以看到,默认的工厂在提供了一个容量为 3 的同步缓存池来缓存 ActivityStarter 对象,该对象创建完成之后,该对象创建完成之后,AMTS 就会将接下来启动 Activity 的操作交给 ActivityStarter 来完成。

#ActivityStarter.java
//根据前面传入的参数解析一下必要的信息,并开始启动 Activity
int execute() {
    try {
        int res;
        synchronized (mService.mGlobalLock) {
            .....
            res = executeRequest(mRequest);//开始执行请求
            .....
            return getExternalResult(res);
        }
    } finally {
        onExecutionComplete();
    }
}
#ActivityStarter.java
private int executeRequest(Request request) {
    .......
      //检测Activity启动的权限
    boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, 							resultWho,requestCode, callingPid, callingUid, callingPackage, 										callingFeatureId,request.ignoreTargetSecurity, inTask != null, 										callerApp, resultRecord, resultRootTask);
    abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
            callingPid, resolvedType, aInfo.applicationInfo);
    abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
            callingPackage);

    final ActivityRecord r = new ActivityRecord.Builder(mService)
            .setCaller(callerApp)
            .setLaunchedFromPid(callingPid)
            .setLaunchedFromUid(callingUid)
            .setLaunchedFromPackage(callingPackage)
            .setLaunchedFromFeature(callingFeatureId)
            .setIntent(intent)
            .setResolvedType(resolvedType)
            .setActivityInfo(aInfo)
            .setConfiguration(mService.getGlobalConfiguration())
            .setResultTo(resultRecord)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setComponentSpecified(request.componentSpecified)
            .setRootVoiceInteraction(voiceSession != null)
            .setActivityOptions(checkedOptions)
            .setSourceRecord(sourceRecord)
            .build();

    mLastStartActivityRecord = r;


    mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
            request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
            restrictedBgActivity, intentGrants);

    return mLastStartActivityResult;
}

上面代码中会进行一些校验和判断权限,包括进程检查,intent检查,权限检查等,后面就会创建 ActivityRecord ,每个 Activity 都会对应一个 ActivityRecord 对象,接着就会调用 startActivityUnchecked 方法对要启动的 Activity 做任务栈管理。

#ActivityStarter.java
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity, NeededUriGrants intentGrants) {
    int result = START_CANCELED;
    final Task startedActivityRootTask;
    try {
        mService.deferWindowLayout();
        Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
        result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
        startedActivityRootTask = handleStartResult(r, result);
        mService.continueWindowLayout();
    }

    postStartActivityProcessing(r, result, startedActivityRootTask);

    return result;
}

在大多数初步检查已经完成的情况下开始进行下一步确认拥有必要的权限。 上面的核心方法就是 startActivityInner() 用来检查启动所必须要有的权限

#ActivityStarter.java
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, Task inTask,
        boolean restrictedBgActivity, NeededUriGrants intentGrants) {
      //设置初始化状态
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
            voiceInteractor, restrictedBgActivity);
        //判断启动模式,并且在 mLaunchFlags 上追加对应标记
    computeLaunchingTaskFlags();
        //设置 Activity 的栈
    computeSourceRootTask();
        //设置 LaunchFlags 到 intent 上
    mIntent.setFlags(mLaunchFlags);

      //决定是否应将新活动插入现有任务中。返回null, 如果不是则应将新活动添加到其中的任务进行活动记录
    final Task reusedTask = getReusableTask();

    ......

    //reusedTask 为 null 则计算是否存在可以使用的任务栈
    final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
    //是否需要创建栈  
    final boolean newTask = targetTask == null;
    mTargetTask = targetTask;

    computeLaunchParams(r, sourceRecord, targetTask);

    //检查是否允许在给定任务或新任务上启动活动
    int startResult = isAllowedToStart(r, newTask, targetTask);
    if (startResult != START_SUCCESS) {
        return startResult;
    }

    final ActivityRecord targetTaskTop = newTask
            ? null : targetTask.getTopNonFinishingActivity();
    if (targetTaskTop != null) {
        // Recycle the target task for this launch.
        startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
        if (startResult != START_SUCCESS) {
            return startResult;
        }
    } else {
        mAddingToTask = true;
    }

  
      //如果正在启动的活动与当前位于顶部的活动相同
    //则需要检查它是否应该只启动一次
    final Task topRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
    if (topRootTask != null) {
        startResult = deliverToCurrentTopIfNeeded(topRootTask, intentGrants);
        if (startResult != START_SUCCESS) {
            return startResult;
        }
    }
        
    //复用或者创建新栈
    if (mTargetRootTask == null) {
        mTargetRootTask = getLaunchRootTask(mStartActivity, mLaunchFlags, targetTask, mOptions);
    }
    if (newTask) {
          //新建一个 Task
        final Task taskToAffiliate = (mLaunchTaskBehind &amp;&amp; mSourceRecord != null)
                ? mSourceRecord.getTask() : null;
        setNewTask(taskToAffiliate);
    } else if (mAddingToTask) {
        //复用之前的 Task
        addOrReparentStartingActivity(targetTask, "adding to task");
    }

         ......
    if (mDoResume) {
            // 调用 resumeFocusedTasksTopActivities方法
      mRootWindowContainer.resumeFocusedTasksTopActivities(
                    mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
    }
    mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
    .....
    return START_SUCCESS;
}

在上面方法中,根据启动模式计算出 flag,然后在根据 flag 等条件判断要启动的 Activity 的 ActivityRecord 是需要新创建 Task 栈 还是加入到现有的 Task 栈。

在为 Activity 准备好 Task 栈之后,调用了 mRootWindowContainer.resumeFocuredTasksTopActivities 方法。

#RootWindowContainer.java
boolean resumeFocusedTasksTopActivities(
        Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
        boolean deferPause) {
    boolean result = false;
    if (targetRootTask != null &amp;&amp; (targetRootTask.isTopRootTaskInDisplayArea()
            || getTopDisplayFocusedRootTask() == targetRootTask)) {
        result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,deferPause);
    }
    return result;
}
#Task.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,boolean deferPause) {
    if (mInResumeTopActivity) {
        // Don't even start recursing.
        return false;
    }

    boolean someActivityResumed = false;
    try {
        // Protect against recursion.
        mInResumeTopActivity = true;
        ....
        someActivityResumed = resumeTopActivityInnerLocked(prev,options,deferPause);
    } finally {
        mInResumeTopActivity = false;
    }

    return someActivityResumed;
}
#Task.java
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
        boolean deferPause) {
    if (!mAtmService.isBooting() &amp;&amp; !mAtmService.isBooted()) {
        // Not ready yet!
        return false;
    }

    // 在当前 Task 栈中找到最上层正在运行的 Activity
    // 如果这个 Activity 没有获取焦点,那这个 Activity 将会被重新启动
    ActivityRecord next = topRunningActivity(true /* focusableOnly */);


    if (next.attachedToProcess()) {
        ......
    } else {
        ......
        //调用 ActivityTaskSupervisor.startSpecificActivity
        mTaskSupervisor.startSpecificActivity(next, true, true);
    }

    return true;
}
#ActivityTaskSupervisor.java
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        // 获取目标进程
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        if (wpc != null &amp;&amp; wpc.hasThread()) {
            try {
                //如果进程存在,启动 Activity 并返回
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
               
            }
            knownToBeDead = true;
        }
        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
        final boolean isTop = andResume &amp;&amp; r.isTopRunningActivity();
        // 进程不存在,则创建进程,并启动 Activity
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }

如果进程不存在,则会创建进程,如果进程存在,则执行此方法

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

    // 创建启动 Activity 的事务
    // proc.getThread() 获取的是一个 IApplicationThread 对象
    final ClientTransaction clientTransaction = ClientTransaction.obtain(
              proc.getThread(), r.appToken);

    final boolean isTransitionForward = r.isTransitionForward();
    // 为事务设置 Callback LaunchActivityItem,在客户端时会被调用
    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.getSavedState(), r.getPersistentSavedState(), results, newIntents,
            r.takeOptions(), isTransitionForward,
            proc.createProfilerInfoIfNeeded(), r.assistToken, 					
            activityClientController,
            r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,
            r.getLaunchedFromBubble()));

     // 生命周期对象
     final ActivityLifecycleItem lifecycleItem;
     if (andResume) {
         lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
     } else {
         lifecycleItem = PauseActivityItem.obtain();
     }
     // 设置生命周期请求
     clientTransaction.setLifecycleStateRequest(lifecycleItem);

     // 执行事务
     mService.getLifecycleManager().scheduleTransaction(clientTransaction);

    return true;
}

上面代码的核心就是创建事务实例,然后来启动 Activity 。

ClientTransaction 是一个容器,里面包含了一些列的消息,这些消息会被发送到客户端,这些消息包括了一系列的回调和一个最终的生命周期状态。

ActivityLifecycleItem 用来请求 Activity 应该到达那个生命周期。

ClientLifecycleManager 用来执行事务

接着上面的代码往下走,就到了 scheduleTransaction():

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    // AIDL 接口,在客户端被实现,也就是 app 中
    final IApplicationThread client = transaction.getClient();
    //执行事务
    transaction.schedule();
    if (!(client instanceof Binder)) {
        transaction.recycle();
    }
}
public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this);
}

mClient 就是 IApplicationThread 的实例,这里是一个 IPC 调用,会直接调用到 App 进程中,并传入了 this,也就是 ClientTransaction 对象。

IApplicationThread 是 ApplicationThread 所实现的,他是 ActivityThread 的内部类:

private class ApplicationThread extends IApplicationThread.Stub {
    @Override
    public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        ActivityThread.this.scheduleTransaction(transaction);
    }
}

我们用一张图来描述一下上面的流程

image-20221222154413841

image-20221222154413841

在上面代码中检查 intent 以及各种权限,并且会获取启动模式,设置启动 Activity 的Task,最后判断 Activity 所在的进程是否存活,如果不存在则创建,如果存在则会通过 IPC 回调到 ApplicationThread 中去。

三、ActivityThread

通过上面,我们知道了启动 Activity 最终有回调到 ApplicationThread,而它又是 ActivityThread 的子类。所以 上面代码最终调用到了 ActivityThread 的父类 ClientTransactionHandler 中:

void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);//处理
      //发送消息
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
//创建的时候传入了 ActivityThread 实例
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);

#ActivityThread$H
case EXECUTE_TRANSACTION:
    final ClientTransaction transaction = (ClientTransaction) msg.obj;
    mTransactionExecutor.execute(transaction);
    if (isSystem()) {
        transaction.recycle();
    }
    break;

上面代码中通过 TransactionExecutor 来执行事务:

public void execute(ClientTransaction transaction) {
    //执行回调
    executeCallbacks(transaction);
    //处理生命周期状态
    executeLifecycleState(transaction);
    mPendingActions.clear();
    if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}

//处理生命周期状态
private void executeLifecycleState(ClientTransaction transaction) {
    final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
    if (lifecycleItem == null) {
        // No lifecycle request, return early.
        return;
    }

    final IBinder token = transaction.getActivityToken();
    final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
    if (DEBUG_RESOLVER) {
        Slog.d(TAG, tId(transaction) + "Resolving lifecycle state: "
                + lifecycleItem + " for activity: "
                + getShortActivityName(token, mTransactionHandler));
    }

    if (r == null) {
        // Ignore requests for non-existent client records for now.
        return;
    }

    // 切换到对应的生命周期
    cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);

    // Execute the final transition with proper parameters.
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
    lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}

private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
        ClientTransaction transaction) {
    final int start = r.getLifecycleState();

    final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
    performLifecycleSequence(r, path, transaction);
}

//执行生命周期状态
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
        ClientTransaction transaction) {
    final int size = path.size();
    for (int i = 0, state; i < size; i++) {
        state = path.get(i);
        switch (state) {
            case ON_CREATE:
                mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                        null /* customIntent */);
                break;
            case ON_START:
                mTransactionHandler.handleStartActivity(r, mPendingActions,
                        null /* activityOptions */);
                break;
            case ON_RESUME:
                mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
                        r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                break;
            case ON_PAUSE:
                mTransactionHandler.handlePauseActivity(r, false /* finished */,
                        false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                        "LIFECYCLER_PAUSE_ACTIVITY");
                break;
            case ON_STOP:
                mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
                        mPendingActions, false /* finalStateRequest */,
                        "LIFECYCLER_STOP_ACTIVITY");
                break;
            case ON_DESTROY:
                mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
                        0 /* configChanges */, false /* getNonConfigInstance */,
                        "performLifecycleSequence. cycling to:" + path.get(size - 1));
                break;
            case ON_RESTART:
                mTransactionHandler.performRestartActivity(r, false /* start */);
                break;
            default:
                throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
        }
    }
}

由于是新启动的 Activity,所以最开始执行的是 ON_CREATE 状态,也就是 handleLaunchActivity 方法, 而 mTransactionHandler 则是从构造方法中传入的,所以这里调用你的就是 ActivityThread 中的方法。

#ActivityThread.java
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
    
      //获取 Activity 的实例
    final Activity a = performLaunchActivity(r, customIntent);

    return a;
}
#ActivityThread.java
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ActivityInfo aInfo = r.activityInfo;

    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        //反射创建 Activity 
        java.lang.ClassLoader cl = appContext.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        ......
    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to instantiate activity " + component
                + ": " + e.toString(), e);
        }
    }

    try {
        //如果没有 Application ,则进行创建
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);

        ......
        if (activity != null) {
            Window window = null;
            if (r.mPendingRemoveWindow != null &amp;&amp; r.mPreserveWindow) {
                window = r.mPendingRemoveWindow;
                r.mPendingRemoveWindow = null;
                r.mPendingRemoveWindowManager = null;
            }
                         ....
            // 加载资源
            appContext.getResources().addLoaders(
                    app.getResources().getLoaders().toArray(new ResourcesLoader[0]));
            // 调用 attach 方法
            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, r.shareableActivityToken);

            //回调 onCreate 方法
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
           
        }
        //设置当前状态
        r.setState(ON_CREATE);
                ......
    } 
    return activity;
}

回调到 ActivityThread 后,会发送一个 EXECUTE_TRANSACTION 消息,处理 system_server 传过来的 ClientTransaction。

具体的处理是在 TransactionExecutor 的 execute 方法中完成的,在里面会先执行各种回调,然后处理并切换到对应的生命周期。在根据对应的什么周期执行对应的方法。由于这里是新建的 aCTIVITY ,所以状态是 ON_CREATE,就会执行 handleLaunchActivity 方法。

接着就会调用 performLaunchActivity 创建 Activity 的实例,调用 attach 初始化 activity,最后回调 activity 中的 onCreate 方法。

总结一下流程
  1. 调用 Activity 的 startActivity 方法来启动目标 Activity
  2. 接着就会调用到 Instrunmentation 的 execStartActivity 方法,通过获取 ATMS 的 binder 代理对象,然后调用到 ATMS 的 startActivity 中去
  3. 调用到 ATMS 中后,会执行到ActivityStarter 的 execute 方法,内部最终执行到了 executeRequest ,接着就会进行一些校验和判断权限,包括进程检查,intent检查,权限检查等,后面就会创建 ActivityRecord ,用来保存 Activity 的相关信息,
  4. 然后就会根据启动模式计算 flag ,设置启动 Activity 的 Task 栈。
  5. 在 ActivityTaskSupervisor 中检查要启动的 Activity 进程是否存在,存在则向客户端进程 ApplicationThread 回调启动 Activity,否则就创建进程。
  6. 会调到 ActivityThread 后在 TransactionExecute 中开始执行system_server回调回来的事务,处理各种回调,切换到对应的生命周期
  7. 最后又回调到 ActivityThread 的 handleLaunchActivity 来启动 Activity。在其中调用了 performLaunchActivity 方法。
  8. 在 performLaunchActivity 中通过反射创建 Activity 实例,如果没有 Application 则先进行创建,然后再调用Activity 的 attach 方法进行初始化,最后回调 activity 的 onCreate 方法。

更多Android进阶指南 可以扫码 解锁 《Android十大板块文档》

1.Android车载应用开发系统学习指南(附项目实战)

2.Android Framework学习指南,助力成为系统级开发高手

3.2024最新Android中高级面试题汇总+解析,告别零offer

4.企业级Android音视频开发学习路线+项目实战(附源码)

5.Android Jetpack从入门到精通,构建高质量UI界面

6.Flutter技术解析与实战,跨平台首要之选

7.Kotlin从入门到实战,全方面提升架构基础

8.高级Android插件化与组件化(含实战教程和源码)

9.Android 性能优化实战+360°全方面性能调优

10.Android零基础入门到精通,高手进阶之路

敲代码不易,关注一下吧。ღ( ´・ᴗ・` ) 🤔

Android Activity的启动流程(Android-10) 深入认识startActivity(Intent) 阅读详情

相关推荐

Android Activity 启动流程分析_android activity工作流程

/根据前面传入的参数解析一下必要的信息,并开始启动 Activity。//通过 Binder 调用 ATMS 启动 Activity。* ActivitySatrter 最大数量。//检测Activity启动的权限。//设置 Activity 的栈。//应用端 AIDL 实现类。//处理生命周期状态。//处理生命周期状态。//执行生命周期状态。

2501_90225886的博客 963

Activity 的启动流程(Android 13)

Activity 的启动过程分为两种:一种是普通 Activity 的启动过程,另一种是根 Activity 的启动过程。普通 Activity 指的是除应用程序启动的第一个 Activity 之外的其他 Activity。

xingyu19911016的博客 2万+

【Android】源码分析 - Activity启动流程,android社招面试

目前已经更新的部分资料:一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!V获取:vip204888 (备注Android)**[外链图片转存中…(img-1SNiqooY-1712683580112)][外链图片转存中…(img-shQXLeX5-1712683580112)]

2401_84102915的博客 1125

Android--Activity启动过程梳理

当从某一个Activity跳转打开另一个Activity显示在屏幕,其中涉及的Activity的启动过程大致分为5部分内容: 1. 当前Activity调用ATMS系统进程过程; 2. ATMS向AMS发送创建应用进程的过程; 3. AMS向Zygote进程发送创建应用进程ActivityThread的过程; 4. Zygote进程fork复制进程并启动应用进程; 5. 应用进程ActivityThread启动Activity的过程;

大模型训练 2380

Activity 的启动流程分析 (基于 Android 8.1 )

0. 前言 Activity 组件的启动流程在 Android 8.0 版本以后得到了很大程度上的变更,很多类或方法已经废弃不用,本人参考最新源代码与指导书籍重新分析 Activity 启动流程,其中大都是自己的观点,如有错误,烦请不吝赐教。 1. 启动调用 作为android四大组件之一,同时也是唯一可被用户感知的部分, Activity 的作用和地位毋庸置疑,而实际开发中,我们要启动...

bestcxcxj的博客 2560

基于Android-28 的源码 Activity 启动流程分析

之前介绍了Android IPC通信机制 Binder,接下来开始梳理Activity启动流程。 常见的Activity的启动有两种方式: 通过LaunchActivity启动一个应用,启动Activity。 通过同一个进程内的startActivity。 以下是基于Android 28的源码进行分析,顺便说一个AS很好用的快捷键:ctrl+shift+N 搜索打开文件 在接下来的流程分析会接...

三木仔 2828

【Android 14源码分析】Activity启动流程-2

在 Launcher 进程构建了启动参数放在了 ActivityOption 中,然后通过 Bundle 传递给 system_service 端AMS 先解析参数,放在了 Request 这个类中保存AMS 构建出一个 ActivityRecord ,这个类在 system_service 端就代表着 Activity ,同时也是一个窗口容器再构建出一个 Task 挂载到窗口树上。

隔壁小王的博客 2789

基于android10.0源码分析Activity的启动流程

一、梳理源码流程干什么 Activity是四大组件中最重要的组件之一,下面来分析Activity的启动过程,了解Activity的启动过程能帮助我们更好的对组件Activity的理解,也能帮助我们更好的把控Activity生命周期的变化过程。 当然Activity作为四大组件之首,10.0版本的Activity的代码函数在8000行,关联的一些类Instrumentation、ActivityTaskManager、ActivityStarter等等,怎么也是几万行的代码,一次完全分析起来会很困难,这里面主

HYM BLOG 1741

Android的Activity启动流程分析

-------------------------------------------------------------------------------------------------------------------------------------------------------------------...

grandself的博客 4万+

图解Activity启动流程

看一百遍不如做一遍,道理都懂,那么赶紧做出第一步吧!

Android小码家 3506

Activity启动完整流程分析-基于Android14源码

本文分析了Android 14中Activity启动的完整流程,重点剖析了应用进程与系统服务(AMS/ATMS)之间的交互机制。主要内容包括: 整体架构概览: 应用进程侧(ActivityThread、ApplicationThread等)与系统服务侧(AMS/ATMS)的组件分工 通过Binder IPC和LocalServices两种通信方式实现跨进程和进程内交互 详细调用链路: 应用进程启动入口ActivityThread.main() 向AMS注册的attach流程 AMS处理应用注册的核心逻辑 涉

保持专注,保持热爱 1622

Android 11 Activity启动流程分析

Android 11 Activity启动流程分析 本片文章是基于Android 11版本来分析应用Activity的启动的,Activity是Android四大组件中最重要的一个,因为我们所有的页面基本上都是基于Activity开发的,所以了解Activity是怎么启动的是很有必要的,接下来我们就来分析一下Activity的启动流程。 Activty启动调用时序图 下面我们就来根据这张时序图来具体看一下代码中的调用流程 我们一般在开发中会用下面的方法来启动一个Activity,那我们分析源码的如果其实就

guojingbu的博客 2987

Win11+Ubuntu18.04+Ubuntu20.04三系统安装与卸载

以下情况均为个人情况:1.插入启动 U 盘后,登录时可以按F12(拯救者Y7000,不同电脑不同)进入BIOS,选择从启动盘启动。2.。3.5.在win基础上,安装第一个Ubuntu系统后,系统启动界面类似如下第一张图,Ubuntu不显示版本号。安装第二个Ubuntu系统后,系统启动界面如下第二张图,如果想更改启动项的名称,可自行查阅相关资料。

weixin_61686291的博客 2536

Android framework 源码分析一Activity启动流程(android 8.0)

Android framework 源码分析之Activity启动流程android 8.0概述Activity的启动流程 概述 Android系统对四大组件的工作过程进行了很大程度的封装,方便开发者使用,Activity作为Android中四大组件之一,直接跟用户进行交互,对于用户来说activity就是应用的一切,系统对其工作流程当然也做了很多封装,本篇文章将介绍Activity的启动流程,在...

马彦虎的博客 7089

基于ESP32的气象雷达站设计与实现

物联网技术通过嵌入式设备实现环境数据的实时采集与可视化,其中ESP32凭借其双核处理器和WiFi/蓝牙功能成为热门选择。本项目利用ESP32结合LVGL图形库,构建了一个低成本气象监测系统,通过OpenWeatherMap API获取全球气象数据并在7英寸触摸屏上动态展示。系统采用三级优化策略处理高分辨率雷达图,包括服务端预处理、硬件加速解码和显示增强,有效解决了内存占用和帧率问题。在物联网设备开发中,类似方案可应用于智能家居、农业监测等场景,特别是需要实时数据可视化的领域。通过SPIFFS存储和zlib压

weixin_42524864的博客 422

Xilinx DMA IP核心配置与实战解析

本文介绍了Xilinx DMA IP核在直接寄存器模式下的配置与工作流程。DMA通过AXI4-Lite接口接收指令,实现内存与数据流之间的高速传输,无需CPU介入。文章详细说明了开发环境配置、IP参数设置(包括地址位宽、数据宽度等关键参数)以及寄存器操作流程。通过仿真分析,展示了读操作中AXI4接口的突发传输机制,包括地址、长度和突发大小的配置。文中还提供了寄存器地址映射表、信号定义等关键信息,为DMA IP核的应用开发提供了实用参考。

weixin_37688766的博客 884

Android4.4 Activity启动流程分析

Android4.4 Activity启动流程分析 $ adb logcat -v time -s ActivityManager  --------- beginning of /dev/log/main  --------- beginning of /dev/log/system  07-01 08:35:20.039 V/ActivityManager( 844): Broadca

shatelang的专栏 1万+

逆向攻防世界CTF系列40-ReverseMe-120

注意sub_401000main中只传了两个参数,但是跟进后发现四个(可能是隐式传递,放在寄存器里传递了),调试发现a4是输入长度,与最终的you_know_how_to_remove_junk_code比较的是v12(但是并没有被传入),开始怀疑是不是隐式传递了。_mm_xor_si128用于计算128位(16字节)的按位异或,然后通过v14控制循环结束的条件,可以看到v14增长的步长为16,而且通过上面得到的flag值解码得到的字符串为32个字节大小,正好是16的整数倍。

LH1013886337的博客 1407

android pendingintent.send()启动activity失败_安卓系统应用启动流程分析

随着移动开发的兴起,安卓系统的重要性愈加突显。本文简要介绍安卓系统上应用启动流程,对于应用开发、系统定制以及性能优化人员来说,熟悉应用启动流程会使得在今后的工作中更加得心应手,做到知其然,知其所以然。本文主要面向开发人员,假定读者已有一定的安卓基础。本文以安卓P版本为基础,不同安卓版本上应用启动流程略有差异,但核心逻辑仍然一致。安卓上应用启动的几种形式冷启动这种方式应用需要完成完整的启动...

weixin_29941275的博客 1658

Close-By Site Assignment,门店近邻关系在 SAP Retail 物料搜索里的真实价值

SAP零售模块中的"Close-By Site Assignment"功能常被低估,但它在门店现场业务中极为关键。该功能允许预先定义各门店间的近邻关系,当导购或店长查询商品时,系统会自动展示附近门店的库存、价格和促销信息。与单纯的地理距离不同,这种近邻关系可基于调拨频率、业务关联度等业务逻辑定义。维护入口在事务码WSD_CBP中,支持按应用场景(如销售、采购)分别设置不同近邻关系。该功能不同于组织结构,专注于增强搜索体验,特别适合多门店运营场景,能有效提升跨店查询效率。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 4851

YOLOv5源码逐行超详细注释与解读(2)——推理部分detect.py

全网最详细的YOLOv5之推理部分detect.py源码逐行注释,近四万字的超详细讲解!小白入门必看!

路人贾的博客 5万+

Activity 启动流程分析(Android10)

概览 Activity 启动流程比较复杂,分析起来很容易陷入复杂的代码中去,所以我这篇分析文章不会深入的分析代码细节,尽量抛开不重要的东西把启动流程按照重点分成几个部分来分析。 下图是 Activity 启动流程的总览。 (上图红色方块是与 WMS 关联的部分,后面会从这里开始介绍 WMS) 后面我们将以 Android 29 为例,按照上图步骤逐步分析。 Intent 解析到 Activity 调用 startActivity 之后,经过几步辗转最终会调用到 AMS 中,而 AMS 又会调用 Activ

张可的博客 4611

目标检测YOLO实战应用案例100讲-基于YOLOv7的番茄采摘机械手场景感知及试验(下)

根据软件系统的设计需求,制定系统的可行性方案分析,编写系统的相关程序和 调试运行环境,对系统进行测试,以实现对番茄数据的采集及监测。登陆界面登陆后,进入选择界面,菜单包括了对番茄种植棚室的固定相机数据的监测、 对番茄采摘机械手的双目相机采集的番茄的静态、动态数据的获取、对番茄静态、动态数 据处理的功能菜单等选项。与利用人工去进行对于番茄果实的识别和数目的统计相比,番茄视觉系统自动记录番 茄数量以及红色已经成熟的番茄、青色未成熟番茄的数量,减轻人工记录的工作量,减少 人工记录的误差,从经济方面是可行的。

qq_36130719的博客 812

App 竟然是这样跑起来的 —— Android App_Activity 启动流程分析

纵观整个过程,从 Launcher 到 AMS、从 AMS 再到 Zygote、再从 Zygote 到 ActivityThread,最后在 ActivitThread 中层层调用到 Activity 的生命周期方法,中间涉及到了无数的细节,但总体上脉络还是非常清晰的,各个 Android 版本的 Framework 层代码可以某些过程的实现不太一样,但是整个调用流程大体上也是相同的,借用Gityuan系列文章按下电源键后竟然发生了这一幕 —— Android 系统启动流程分析。

2401_84149635的博客 1032

基于Qt C++开发一套大疆农业无人机的AI飞控系统

如果需要补充**多机协同作业代码**、**农田测绘数据导出**、**作业数据统计大屏**或**移动端地面站适配**功能,可以告知具体需求,我会针对性完善。"开启" : "关闭") << "喷洒,流量:" << flowRate << "L/min";emit errorOccurred(QString("SDK初始化失败,错误码:%1").arg((int)ret));report += QString("问题区域数量:%1\n").arg(info.problemAreas.size());

寒寒豆豆软件公司的博客 380

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

上一篇: Android | 输入系统(IMS)
下一篇: Android仿微信录制小视频
不秃头de程序猿
博客等级 码龄5年 4089粉丝 1475原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值