【Android 启动过程】Activity 启动源码分析 ( ActivityThread -> Activity、主线程阶段 一 )

简介: 【Android 启动过程】Activity 启动源码分析 ( ActivityThread -> Activity、主线程阶段 一 )

文章目录

前言

一、ClientTransactionHandler.scheduleTransaction

二、ActivityThread.H 处理 EXECUTE_TRANSACTION 消息

三、TransactionExecutor execute -> executeCallbacks 方法

四、LaunchActivityItem.execute

总结

前言

上一篇博客 【Android 启动过程】Activity 启动源码分析 ( AMS -> ActivityThread、AMS 线程阶段 二 ) 分析到 , 在 AMS 进程通过 Binder 机制调用 ActivityThread 中的 ApplicationThread 内部类中 scheduleTransaction 方法 ;


在该方法中 , 发送了 ActivityThread.H.EXECUTE_TRANSACTION 159 159159 消息 , 由 ActivityThread 中的内部类 H 处理该消息 ;


从 Binder 调用 ActivityThread 开始 , 就进入了主线程阶段开始执行 , 这里开始在主线程中创建 Activity , 并启动该 Activity ;






一、ClientTransactionHandler.scheduleTransaction


在 ClientTransactionHandler.scheduleTransaction 方法中 , 发送了 159 159159 消息 , 并且将参数 ClientTransaction transaction 传递给了 ActivityThread.H ;


/**
 * 定义{@link android.app.servertransaction.ClientTransaction}或其项可以在客户端上执行的操作。
 * @hide
 */
public abstract class ClientTransactionHandler {
    // 安排与阶段相关的逻辑和处理程序。
    /** 准备并安排事物执行。 */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
}


完整代码参考 /frameworks/base/core/java/android/app/ClientTransactionHandler.java ;






二、ActivityThread.H 处理 EXECUTE_TRANSACTION 消息


在 ActivityThread 的 H 内部类中 , 处理 int EXECUTE_TRANSACTION = 159 消息时 , 获取传入的 ClientTransaction transaction 对象 , 并执行该事务 mTransactionExecutor.execute(transaction) ;


mTransactionExecutor 是 ActivityThread 成员变量 , 是执行多步骤事务的执行者 ;


/**
 * 它管理应用程序进程中主线程的执行、调度和执行活动、广播以及活动管理器请求的其他操作。
 *
 * {@hide}
 */
public final class ActivityThread extends ClientTransactionHandler {
    // 执行多步骤事务的执行者。
    private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
    class H extends Handler {
        public static final int EXECUTE_TRANSACTION = 159;
        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                case EXECUTE_TRANSACTION:
                  // ActivityThread 调用 scheduleTransaction 方法发送 159 消息时
                  // 将 transaction 传递到了 H 中
                  // 此处获取该 transaction 
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    // 执行 transaction 相关信息 
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        // 系统进程内的客户端事务在客户端而不是ClientLifecycleManager上循环,
                        // 以避免在处理此消息之前被清除。
                        transaction.recycle();
                    }
                    // TODO(lifecycler): 回收本地计划的事务。
                    break;
            }
            Object obj = msg.obj;
            if (obj instanceof SomeArgs) {
                ((SomeArgs) obj).recycle();
            }
            if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
        }
    }
}


完整代码参考 /frameworks/base/core/java/android/app/ActivityThread.java






三、TransactionExecutor execute -> executeCallbacks 方法


分析 ActivityThread 的 TransactionExecutor mTransactionExecutor = new TransactionExecutor(this) 成员的 mTransactionExecutor.execute(transaction) 方法 , 执行事务的过程 ;


传入的参数 ClientTransaction transaction 实际上就是 ActivityThread ;


在 execute 方法中 , 调用了 executeCallbacks 方法 , 在该方法中从 ClientTransaction 获取 ClientTransactionItem 集合 , 最终调用 了 ClientTransactionItem 的 execute 方法 , item.execute(mTransactionHandler, token, mPendingActions) ;


/**
 * 类以正确的顺序管理事务执行。
 * @hide
 */
public class TransactionExecutor {
    /**
     * 解决事务。
     * 首先,所有回调将按照它们在列表中出现的顺序执行。
     * 如果回调需要特定的执行前或执行后状态,则客户端将相应地进行转换。
     * 然后,客户端将循环到最终生命周期状态(如果提供)。
     * 否则,它将保持初始状态或回调所需的最后状态。
     */
    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
        executeCallbacks(transaction);
        executeLifecycleState(transaction);
        mPendingActions.clear();
        log("End resolving transaction");
    }
    /** 循环检查回调请求的所有状态,并在适当的时间执行它们。 */
    @VisibleForTesting
    public void executeCallbacks(ClientTransaction transaction) {
        // 从 ClientTransaction 获取 ClientTransactionItem 集合
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        // 遍历 ClientTransactionItem 集合 , 并执行 ClientTransactionItem 的 execute 方法
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
        }
    }
}


完整代码参考 /frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java ;


上面 TransactionExecutor 中的 executeCallbacks 中遍历的 ClientTransactionItem 集合元素是在 ActivityStackSupervisor 的 realStartActivityLocked 方法的 LaunchActivityItem.obtain(new Intent(r.intent) 码中设置的 ;


public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener,
        RecentTasks.Callbacks {
    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
                // Create activity launch transaction.
                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                        r.appToken);
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        // TODO: Have this take the merged configuration instead of separate global
                        // and override configs.
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                        r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                        profilerInfo));
  }
}


完整代码参考 /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java ;






四、LaunchActivityItem.execute


在 TransactionExecutor.executeCallbacks 中调用了 item.execute(mTransactionHandler, token, mPendingActions) 代码 , 下面继续分析 ClientTransactionItem 的 execute 方法 ,


这里的 ClientTransactionItem 实际上是 LaunchActivityItem , LaunchActivityItem 的 execute 创建 ActivityClientRecord 封装了启动 Activity 的所有必要信息 ,


client.handleLaunchActivity(r, pendingActions, null /* customIntent */) 代码 , client 就是 ActivityThread , 最终调用的是 ActivityThread 的 handleLaunchActivity 方法 ;


/**
 * 请求启动 Activity 。
 * @hide
 */
public class LaunchActivityItem extends ClientTransactionItem {
    @Override
    public void preExecute(ClientTransactionHandler client, IBinder token) {
        client.updateProcessState(mProcState, false);
        client.updatePendingConfiguration(mCurConfig);
    }
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}


完整代码参考 /frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java ;


总结

发送消息给 ActivityThread.H , 然后经过上述一系列调用 , 获取到了启动 Activity 的所有数据 , 又回到 ActivityThread 中执行 handleLaunchActivity 方法 ;



目录
相关文章
|
1月前
|
算法 Java 数据库
Android 应用的主线程在什么情况下会被阻塞?
【10月更文挑战第20天】为了避免主线程阻塞,我们需要合理地设计和优化应用的代码。将耗时操作移到后台线程执行,使用异步任务、线程池等技术来提高应用的并发处理能力。同时,要注意避免出现死循环、不合理的锁使用等问题。通过这些措施,可以确保主线程能够高效地运行,提供流畅的用户体验。
63 2
|
2月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
94 6
|
2月前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
Android面试高频知识点(4) 详解Activity的启动流程
31 3
|
2月前
|
缓存 前端开发 Android开发
Android实战之如何截取Activity或者Fragment的内容?
本文首发于公众号“AntDream”,介绍了如何在Android中截取Activity或Fragment的屏幕内容并保存为图片。包括截取整个Activity、特定控件或区域的方法,以及处理包含RecyclerView的复杂情况。
27 3
|
5月前
|
Android开发
Android面试题之Activity的启动模式和flag
Android Activity的四种启动模式:standard(默认,每次启动创建新实例),singleTop(栈顶复用,不走onCreate,调用onNewIntent),singleTask(栈内唯一,清除上方Activity)和singleInstance(单独栈内唯一)。启动模式在AndroidManifest.xml中配置,Intent Flags如FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_SINGLE_TOP可实现类似功能。了解这些对于处理Activity栈管理至关重要。
57 0
|
7月前
|
XML Java Android开发
利用Bundle实现Android Activity间消息的传递
利用Bundle实现Android Activity间消息的传递
60 2
|
2月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
20 0
|
3月前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
讲解Activity的启动流程了,Activity的启动流程相对复杂一下,涉及到了Activity中的生命周期方法,涉及到了Android体系的CS模式,涉及到了Android中进程通讯Binder机制等等, 首先介绍一下Activity,这里引用一下Android guide中对Activity的介绍:
59 4
|
4月前
|
XML Android开发 数据格式
android中两个Activity同时设定了intent-filter的category为android.intent.category.LAUNCHER,会发生什么情况?
本文通过案例分析了在Android中当两个Activity都设置了`android.intent.category.LAUNCHER`类别时,会导致它们同时在应用启动器的"所有应用"页面显示为不同的启动入口。
114 2
android中两个Activity同时设定了intent-filter的category为android.intent.category.LAUNCHER,会发生什么情况?
|
3月前
|
Android开发 开发者
Android面试之Activity启动流程简述
每个Android开发者都熟悉的Activity,但你是否了解它的启动流程呢?本文将带你深入了解。启动流程涉及四个关键角色:Launcher进程、SystemServer的AMS、应用程序的ActivityThread及Zygote进程。核心在于AMS与ActivityThread间的通信。文章详细解析了从Launcher启动Activity的过程,包括通过AIDL获取AMS、Zygote进程启动以及ActivityThread与AMS的通信机制。接着介绍了如何创建Application及Activity的具体步骤。整体流程清晰明了,帮助你更深入理解Activity的工作原理。
59 0