Activity生命周期调用流程 - 安卓R

Android面试官:我在Activity onResume()之前的任何一个生命周期中调用了finish()后,此Activity的生命周期会如何? 作者:Android王小波 链接:https://juejin.cn/post/7038903088039591943 一、前言: 在Android开发中,Activity是四大组件中最重要的组件,然而Activity的生命周期又是其中最为基础的知识点,所以重要性不言而喻。我刚接触Android不足两年,之前也恶补了生命周期相关的知识,起初自认为了解的比较全面了,直到我被问到了上面的问题,然后我彻底懵了。我面试了许多家公司,大厂小厂都有面试,小厂没有被问到,大厂面试中,第一次是B站有问到我这个问题,我没 阅读详情

Activity生命周期简介

Activity生命周期

Activity生命周期如上图所示,详细的介绍可见安卓生命周期官方文档。

本文主要研究Activity的生命周期相关回调方法调用的流程。

ClientTransaction

ClientTransaction定义在frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java中,其定义的成员变量:

/**
 * A container that holds a sequence of messages, which may be sent to a client.
 * This includes a list of callbacks and a final lifecycle state.
 *
 * @see com.android.server.am.ClientLifecycleManager
 * @see ClientTransactionItem
 * @see ActivityLifecycleItem
 * @hide
 */
public class ClientTransaction implements Parcelable, ObjectPoolItem {

    /** A list of individual callbacks to a client. */
    @UnsupportedAppUsage
    private List<ClientTransactionItem> mActivityCallbacks;

    /**
     * Final lifecycle state in which the client activity should be after the transaction is
     * executed.
     */
    private ActivityLifecycleItem mLifecycleStateRequest;

    /** Target client. */
    private IApplicationThread mClient;

    /** Target client activity. Might be null if the entire transaction is targeting an app. */
    private IBinder mActivityToken;

    ......
    }

ClientTransaction的对象从SystemServer进程通过binder调用传给app进程,其中几个重要的成员变量如下:

mClient:代表此ClientTransaction要传给的app进程;

mActivityToken:代表此ClientTransaction要传给的具体Activity;

mActivityCallbacks:表示需要Activity执行的回调,这个回调可能是进入某个生命周期,或者是例如onConfigurationChanged的回调;

mLifecycleStateRequest:表示Activity最终进入的生命周期,其类型ActivityLifecycleItem是ClientTransactionItem的子类,是具体某个生命周期的回调。

frameworks/base/core/java/android/app/servertransaction/BaseClientRequest.java是ClientTransactionItem的父类,其定义:

/**
 * Base interface for individual requests from server to client.
 * Each of them can be prepared before scheduling and, eventually, executed.
 * @hide
 */
public interface BaseClientRequest extends ObjectPoolItem {

    /**
     * Prepare the client request before scheduling.
     * An example of this might be informing about pending updates for some values.
     *
     * @param client Target client handler.
     * @param token  Target activity token.
     */
    default void preExecute(ClientTransactionHandler client, IBinder token) {
    }

    /**
     * Execute the request.
     * @param client Target client handler.
     * @param token Target activity token.
     * @param pendingActions Container that may have data pending to be used.
     */
    void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions);

    /**
     * Perform all actions that need to happen after execution, e.g. report the result to server.
     * @param client Target client handler.
     * @param token Target activity token.
     * @param pendingActions Container that may have data pending to be used.
     */
    default void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
    }
}

frameworks/base/core/java/android/app/servertransaction/ClientTransactionItem.java定义:

/**
 * A callback message to a client that can be scheduled and executed.
 * Examples of these might be activity configuration change, multi-window mode change, activity
 * result delivery etc.
 *
 * @see ClientTransaction
 * @see com.android.server.am.ClientLifecycleManager
 * @hide
 */
public abstract class ClientTransactionItem implements BaseClientRequest, Parcelable {

    /** Get the state that must follow this callback. */
    @LifecycleState
    public int getPostExecutionState() {
        return UNDEFINED;
    }


    // Parcelable

    @Override
    public int describeContents() {
        return 0;
    }
}

frameworks/base/core/java/android/app/servertransaction/ActivityLifecycleItem.java是ClientTransactionItem的子类,其定义:

/**
 * Request for lifecycle state that an activity should reach.
 * @hide
 */
public abstract class ActivityLifecycleItem extends ClientTransactionItem {

    @IntDef(prefix = { "UNDEFINED", "PRE_", "ON_" }, value = {
            UNDEFINED,
            PRE_ON_CREATE,
            ON_CREATE,
            ON_START,
            ON_RESUME,
            ON_PAUSE,
            ON_STOP,
            ON_DESTROY,
            ON_RESTART
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface LifecycleState{}
    public static final int UNDEFINED = -1;
    public static final int PRE_ON_CREATE = 0;
    public static final int ON_CREATE = 1;
    public static final int ON_START = 2;
    public static final int ON_RESUME = 3;
    public static final int ON_PAUSE = 4;
    public static final int ON_STOP = 5;
    public static final int ON_DESTROY = 6;
    public static final int ON_RESTART = 7;

    /** A final lifecycle state that an activity should reach. */
    @LifecycleState
    public abstract int getTargetState();

    /** Called by subclasses to make sure base implementation is cleaned up */
    @Override
    public void recycle() {
    }
}

SystemServer进程

Activity的onCreate、onStart、onResume等生命周期方法都是由SystemServer进程发起的,调用frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java的scheduleTransaction方法,此方法有多个重载,可以传入已经构建好了的ClientTransaction对象或传入相应参数在scheduleTransaction方法中构建ClientTransaction对象:

/**
 * Class that is able to combine multiple client lifecycle transition requests and/or callbacks,
 * and execute them as a single transaction.
 *
 * @see ClientTransaction
 */
class ClientLifecycleManager {
    // TODO(lifecycler): Implement building transactions or global transaction.
    // TODO(lifecycler): Use object pools for transactions and transaction items.

    /**
     * Schedule a transaction, which may consist of multiple callbacks and a lifecycle request.
     * @param transaction A sequence of client transaction items.
     * @throws RemoteException
     *
     * @see ClientTransaction
     */
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        transaction.schedule();
        if (!(client instanceof Binder)) {
            // If client is not an instance of Binder - it's a remote call and at this point it is
            // safe to recycle the object. All objects used for local calls will be recycled after
            // the transaction is executed on client in ActivityThread.
            transaction.recycle();
        }
    }

    /**
     * Schedule a single lifecycle request or callback to client activity.
     * @param client Target client.
     * @param activityToken Target activity token.
     * @param stateRequest A request to move target activity to a desired lifecycle state.
     * @throws RemoteException
     *
     * @see ClientTransactionItem
     */
    void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
            @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
        final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
                stateRequest);
        scheduleTransaction(clientTransaction);
    }

    /**
     * Schedule a single callback delivery to client activity.
     * @param client Target client.
     * @param activityToken Target activity token.
     * @param callback A request to deliver a callback.
     * @throws RemoteException
     *
     * @see ClientTransactionItem
     */
    void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
            @NonNull ClientTransactionItem callback) throws RemoteException {
        final ClientTransaction clientTransaction = transactionWithCallback(client, activityToken,
                callback);
        scheduleTransaction(clientTransaction);
    }

    /**
     * Schedule a single callback delivery to client application.
     * @param client Target client.
     * @param callback A request to deliver a callback.
     * @throws RemoteException
     *
     * @see ClientTransactionItem
     */
    void scheduleTransaction(@NonNull IApplicationThread client,
            @NonNull ClientTransactionItem callback) throws RemoteException {
        final ClientTransaction clientTransaction = transactionWithCallback(client,
                null /* activityToken */, callback);
        scheduleTransaction(clientTransaction);
    }

    /**
     * @return A new instance of {@link ClientTransaction} with a single lifecycle state request.
     *
     * @see ClientTransaction
     * @see ClientTransactionItem
     */
    private static ClientTransaction transactionWithState(@NonNull IApplicationThread client,
            @NonNull IBinder activityToken, @NonNull ActivityLifecycleItem stateRequest) {
        final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
        clientTransaction.setLifecycleStateRequest(stateRequest);
        return clientTransaction;
    }

    /**
     * @return A new instance of {@link ClientTransaction} with a single callback invocation.
     *
     * @see ClientTransaction
     * @see ClientTransactionItem
     */
    private static ClientTransaction transactionWithCallback(@NonNull IApplicationThread client,
            IBinder activityToken, @NonNull ClientTransactionItem callback) {
        final ClientTransaction clientTransaction = ClientTransaction.obtain(client, activityToken);
        clientTransaction.addCallback(callback);
        return clientTransaction;
    }
}

得到构建好了的ClientTransaction对象后,会调用ClientTransaction的schedule方法:

    /**
     * Schedule the transaction after it was initialized. It will be send to client and all its
     * individual parts will be applied in the following sequence:
     * 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work
     *    that needs to be done before actually scheduling the transaction for callbacks and
     *    lifecycle state request.
     * 2. The transaction message is scheduled.
     * 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes
     *    all callbacks and necessary lifecycle transitions.
     */
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

App进程

通过binder调用了app进程中frameworks/base/core/java/android/app/ActivityThread.java的内部类ApplicationThread的scheduleTransaction方法:

        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }
调用了ActivityThread的父类frameworks/base/core/java/android/app/ClientTransactionHandler.java的scheduleTransaction方法:

    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }

这个消息在ActivityThread的内部类H的handleMessage方法中处理:

        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                ......
                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        // Client transactions inside system process are recycled on the client side
                        // instead of ClientLifecycleManager to avoid being cleared before this
                        // message is handled.
                        transaction.recycle();
                    }
                    // TODO(lifecycler): Recycle locally scheduled transactions.
                    break;
            ......
        }

调用了frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java的execute方法:

    /**
     * Resolve transaction.
     * First all callbacks will be executed in the order they appear in the list. If a callback
     * requires a certain pre- or post-execution state, the client will be transitioned accordingly.
     * Then the client will cycle to the final lifecycle state if provided. Otherwise, it will
     * either remain in the initial state, or last state needed by a callback.
     */
    public void execute(ClientTransaction transaction) {
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");

        final IBinder token = transaction.getActivityToken();
        if (token != null) {
            final Map<IBinder, ClientTransactionItem> activitiesToBeDestroyed =
                    mTransactionHandler.getActivitiesToBeDestroyed();
            final ClientTransactionItem destroyItem = activitiesToBeDestroyed.get(token);
            if (destroyItem != null) {
                if (transaction.getLifecycleStateRequest() == destroyItem) {
                    // It is going to execute the transaction that will destroy activity with the
                    // token, so the corresponding to-be-destroyed record can be removed.
                    activitiesToBeDestroyed.remove(token);
                }
                if (mTransactionHandler.getActivityClient(token) == null) {
                    // The activity has not been created but has been requested to destroy, so all
                    // transactions for the token are just like being cancelled.
                    Slog.w(TAG, tId(transaction) + "Skip pre-destroyed transaction:\n"
                            + transactionToString(transaction, mTransactionHandler));
                    return;
                }
            }
        }

        if (DEBUG_RESOLVER) Slog.d(TAG, transactionToString(transaction, mTransactionHandler));

        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
    }

注意这里首先调用TransactionExecutor的executeCallbacks执行ClientTransaction对象中的所有mActivityCallbacks的回调,然后再调用TransactionExecutor的executeLifecycleState方法进入ClientTransaction对象的目标生命周期mLifecycleStateRequest。

首先来看TransactionExecutor的executeCallbacks方法:

    /** Cycle through all states requested by callbacks and execute them at proper times. */
    @VisibleForTesting
    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        if (callbacks == null || callbacks.isEmpty()) {
            // No callbacks to execute, return early.
            return;
        }
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");

        final IBinder token = transaction.getActivityToken();
        ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

        // In case when post-execution state of the last callback matches the final state requested
        // for the activity in this transaction, we won't do the last transition here and do it when
        // moving to final state instead (because it may contain additional parameters from server).
        final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
        final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
                : UNDEFINED;
        // Index of the last callback that requests some post-execution state.
        final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);

        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
            final int postExecutionState = item.getPostExecutionState();
            final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                    item.getPostExecutionState());
            if (closestPreExecutionState != UNDEFINED) {
                cycleToPath(r, closestPreExecutionState, transaction);
            }

            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            if (r == null) {
                // Launch activity request will create an activity record.
                r = mTransactionHandler.getActivityClient(token);
            }

            if (postExecutionState != UNDEFINED && r != null) {
                // Skip the very last transition and perform it by explicit state request instead.
                final boolean shouldExcludeLastTransition =
                        i == lastCallbackRequestingState && finalState == postExecutionState;
                cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
            }
        }
    }

对每个callbacks中的ClientTransactionItem回调,首先如果需要的话会调用TransactionExecutor的cycleToPath方法让Activity进入最近的前一个生命周期,然后调用ClientTransactionItem的execute方法让Activity进入指定的生命周期或只是执行一个回调。

回到TransactionExecutor的execute方法中,后面还调用了TransactionExecutor的executeLifecycleState方法:

    /** Transition to the final state if requested by the 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;
        }

        // Cycle to the state right before the final requested state.
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);

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

这里首先调用了TransactionExecutor的cycleToPath方法确保让Activity进入最近的前一个生命周期,然后调用ActivityLifecycleItem的execute方法让Activity进入目标生命周期,最后调用了ActivityLifecycleItem的postExecute方法。

看下TransactionExecutor的cycleToPath方法:

    /** Transition the client between states. */
    @VisibleForTesting
    public void cycleToPath(ActivityClientRecord r, int finish, ClientTransaction transaction) {
        cycleToPath(r, finish, false /* excludeLastState */, transaction);
    }

    /**
     * Transition the client between states with an option not to perform the last hop in the
     * sequence. This is used when resolving lifecycle state request, when the last transition must
     * be performed with some specific parameters.
     */
    private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
            ClientTransaction transaction) {
        final int start = r.getLifecycleState();
        if (DEBUG_RESOLVER) {
            Slog.d(TAG, tId(transaction) + "Cycle activity: "
                    + getShortActivityName(r.token, mTransactionHandler)
                    + " from: " + getStateName(start) + " to: " + getStateName(finish)
                    + " excludeLastState: " + excludeLastState);
        }
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        performLifecycleSequence(r, path, transaction);
    }

调用了TransactionExecutor的performLifecycleSequence方法:

    /** Transition the client through previously initialized state sequence. */
    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);
            if (DEBUG_RESOLVER) {
                Slog.d(TAG, tId(transaction) + "Transitioning activity: "
                        + getShortActivityName(r.token, mTransactionHandler)
                        + " to state: " + getStateName(state));
            }
            switch (state) {
                case ON_CREATE:
                    mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                            null /* customIntent */);
                    break;
                case ON_START:
                    mTransactionHandler.handleStartActivity(r.token, mPendingActions);
                    break;
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                    break;
                case ON_PAUSE:
                    mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
                            false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                            "LIFECYCLER_PAUSE_ACTIVITY");
                    break;
                case ON_STOP:
                    mTransactionHandler.handleStopActivity(r.token, 0 /* configChanges */,
                            mPendingActions, false /* finalStateRequest */,
                            "LIFECYCLER_STOP_ACTIVITY");
                    break;
                case ON_DESTROY:
                    mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
                            0 /* configChanges */, false /* getNonConfigInstance */,
                            "performLifecycleSequence. cycling to:" + path.get(size - 1));
                    break;
                case ON_RESTART:
                    mTransactionHandler.performRestartActivity(r.token, false /* start */);
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
            }
        }
    }

这里的mTransactionHandler其实就是ActivityThread,调用其相应的handleLaunchActivity、handleStartActivity、handleResumeActivity、handlePauseActivity、handleStopActivity、handleDestroyActivity或performRestartActivity方法来进一步调用相应的Activity的生命周期方法。

回到TransactionExecutor的executeLifecycleState方法中,后面会调用ActivityLifecycleItem的execute方法让Activity进入目标生命周期,最后还会调用ActivityLifecycleItem的postExecute,例如这里的ActivityLifecycleItem是frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.java:

/**
 * Request to move an activity to resumed state.
 * @hide
 */
public class ResumeActivityItem extends ActivityLifecycleItem {
    ......
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
        client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
                "RESUME_ACTIVITY");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

    @Override
    public void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        try {
            // TODO(lifecycler): Use interface callback instead of AMS.
            ActivityTaskManager.getService().activityResumed(token);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }
    ......
}

这里传进来的ClientTransactionHandler其实就是ActivityThread,这里也是调用了ActivityThread的handleResumeActivity方法来进一步调用相应的Activity的生命周期方法,那么Activity具体是如何启动的可以看Activity的启动流程。

最后在postExecute方法中会通过binder调用frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java的activityResumed方法通知SystemServer此Activity进入了resume状态。

Activity与Fragment的生命周期详解 在安卓中Activity与Fragment是非常相似的两个类,它们各自都拥有自己的生命周期,且都可以用来显示布局文件中的视图。其中Activity是通过setContenView()显示视图,而Fragment是通过在onCreateView()中将布局xml文件解析为一个View然后返回该View来显示视图,也正因为具备相似的功能,所以它们的生命周期也极为相似,熟练掌握它们的生命周期是做出高效稳 阅读详情

相关推荐

LTspice元器件库导入与路径管理:符号、模型、子电路全解析

在电子电路仿真中,元器件库通常由符号、模型和子电路三层构成:符号定义引脚外观,模型描述电气行为,子电路封装多端子网络。理解三者职责边界,是解决 LTspice 元器件库导入报错的关键。许多导入失败并非软件问题,而是文件类型错配、路径引用不清或引脚顺序不一致。掌握 `.include` 指令、用户库搜索路径和自制符号绑定模型,可以提升第三方模型复用效率,降低跨项目迁移成本。该思路适用于运放、MOS 管、二极管等器件建模,尤其在 UA741 等经典运放导入场景中,需要先核对 `.subckt` 引脚顺序,再选择

weixin_29182481的博客 181

【Activity】基于Android9.0的startActivity流程分析(3):新Activity的onStart流程、onResume流程

目录 3. 新Activity的onStart流程 4. 新Activity的onResume流程 4.1 ResumeActivityItem.execute 4.2ActivityThread.handleResumeActivity 4.2.1 ActivityThread.performResumeActivity 4.2.2Looper.myQueue().addIdle...

明朗晨光的专栏 4348

EDKII实战:手把手调试PciHostBridge.c,看UEFI如何分配你的PCIe设备资源(IO/Memory空间)

本文深入解析EDKII中PciHostBridge.c模块的工作原理,详细指导如何调试PCIe设备资源分配(IO/Memory空间)。通过实战案例展示UEFI环境下Root Bridge初始化、地址空间转换及协议安装等核心流程,提供常见问题排查方法与性能优化建议,帮助开发者解决PCIe设备兼容性问题。

weixin_29201933的博客 209

从源码看 Activity 生命周期(上篇)

本文是我的AOSP 系列第六篇文章,往期目录如下:Java 世界的盘古和女娲 —— ZygoteZygote家的大儿子 —— SystemServerAndroid 世界中,谁喊醒了...

秉心说 418

解决vscode无法运行npm命令的问题(cmd可行)

Powershell以及vscode中npm命令使用不了

无痕坚守本心的博客 2750

Obsidian和Typora图片路径同步终极指南:告别混乱的assets文件夹

本文详细解析了Obsidian与Typora图片路径同步的终极解决方案,通过Custom Attachment Location插件实现动态路径管理,解决了两款工具间图片兼容性问题。文章提供了从基础配置到高级应用的完整指南,帮助用户告别混乱的assets文件夹,提升工作效率。

g9h0i1的博客 823

Activity的onStart()调用时机

我们知道正常生命周期由 -> -> ,但是我们在启动的时候并没有向请求处理,而是创建了一个和:(具体启动流程文章请看,) 然后会由来处理消息,此时为上面创建的对象,内部的中有, 对象为。[源码请看:] 在中间接调用处理事务: 到这需要看一下和的类结构和重要常量 处理 -----> 处理 -----> :修正生命周期 在中需要修正生命周期请求以确保正确的生命周期循环!通过调用方法(抽象的命名=_=) : 经过上面的重新链接,返回的生命周期链为,接下来继续执行

C_biubiubiu的博客 2775

GD32H7系列SRAM优化配置实战指南

本文详细解析了GD32H7系列MCU的SRAM架构,包括ITCM、DTCM、AXI SRAM等关键内存区域的特点与性能差异。通过实战指南,指导开发者如何通过配置寄存器和链接脚本,优化内存布局以提升系统性能,并重点探讨了DMA操作与CPU缓存一致性的解决方案,帮助充分发挥GD32H7的高性能潜力。

weixin_29169899的博客 518

如何分析Activity生命周期的log

一、查看log的方向和方式 涉及到Activity生命周期问题时,主要是查看event log(logcat -b events),本地可使用adb logcat -b events | grep am_ 涉及到某个生命周期(一般指am_on_xxx)耗时时,结合"Slow Looper main"查看是哪个消息耗时 app端log的形式: am_on_xxx_called: [userId,className,reason,duration] ,duration是miui加上的 二、常见场景的lo

xiaoyantan的博客 5570

拆解特斯拉Optimus的关节技术:谐波减速器在仿人机器人中的5个精妙设计

本文深度解析特斯拉Optimus仿人机器人关节中的谐波减速器技术,揭示其五大工程突破:微型化材料革命、两万分之一圈精度实现、碳纤维柔轮轻量化、智能运维系统及国产替代方案。重点探讨谐波减速器如何通过创新设计和先进材料实现精准传动,为仿人机器人提供高效可靠的关节动力解决方案。

omega的博客 1077

2026基金本子新规必看!聚焦四大底层问题,利用AI辅助分别破解提升中标率

我拟申报的研究主题为【明确的研究主题或关键词组合】。选题方向也是评审专家关注的核心之一,申报前可以检索近五年领域前人中标项目,分析现有研究的空白与不足,并结合自身研究基础选择 “人无我有、人有我优” 的细分方向,如果是交叉学科选题,则要阐述不同学科的融合逻辑与创新点。“推动国家战略”、“带来行业发展”等宏观表述,有很多同仁都喜欢用这类话术开篇,但实际上宏大叙事无法替代具体的真实科学问题,明确不了研究要解决的核心痛点,更没有说明问题的现实针对性,评审看了往往抓不到研究的核心价值。

智能AI让学术科研更容易 295

Android 9.0 Activity的OnPuse方法执行过程分析

上篇文章 分析了点击桌面图标,启动Activity的过程分析,由于篇幅的原因,将Activity启动过程中,上一个Activity,也就是Launcher进程的Launcher这个Activity的OnPause方法未分析,这篇文章就分析Activity的OnPause方法的执行过程。接着上篇文章的ActivityStackSupervisor类的resumeTopActivityInnerLoc...

hujin2017的博客 698

6、Cocos2D游戏开发:精灵添加与角色实现

本文详细介绍了在Cocos2D游戏开发中如何添加背景精灵和玩家角色精灵。通过创建GameScene场景、组织项目资源、使用多分辨率图像适配不同设备,并深入讲解了将角色拆分为上下半身以实现更真实瞄准效果的原理。文章还解析了Cocos2D的图像搜索机制、锚点概念及其应用,以及如何通过父子节点关系管理复合角色。最终实现了猎人角色在场景中的正确显示与定位,为后续动画和交互功能打下基础。

e3f4g5的博客 90

Android Activity生命周期详解

Activity作为Android的四大组件之一,非常的重要,也是最常用的四大组件,使用Activity必须要在AndroidManifest中进行注册,那么作为Android的基础,Activity的生命周期你是否完全掌握了呢?下面就让我们来一起回顾一下Activity的生命周期吧! 首先,你需要知道 Activity的生命周期分为两种。   典型情况下的生命周期(就是我们开发中经常用到的...

李家大大大公子 2万+

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Android R Activity启动流程

上述两种情况无疑是根Activity的启动流程是最为复杂的,而且里面的流程也会涉及到普通Activity的启动流程,所以直接从根Activity的启动流程开始分析。

m0_61097519的博客 2110

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【安卓 R 源码】Activity 启动流程及其生命周期源码分析

1. Activty 的生命周期 activity的生命周期 oncreate()->onstart()->onResume()->onPause()->onStop()->onDestory() onCreate(): 当我们点击activity的时候,系统会调用activity的oncreate()方法,在这个方法中我们会初始化当前布局setContentLayout()方法。 onStart(): onCreate()方法完成后,此时activity进入.

mike_jun的博客 4365

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Android-Activity生命周期

Activity作为Android的四大组件之一,非常的重要,也是最常用的四大组件,使用Activity必须要在AndroidManifest中进行注册,那么作为Android的基础,Activity的生命周期你是否完全掌握了呢?下面就让我们来一起回顾一下Activity的生命周期吧!

迷雾总会解 4815

【Android Activity】Activity的生命周期

onCreate:表示Activity正在被创建。生命周期的第一个方法,当打开一个activity时首先回调这个方法。在这个方法中一般做一些初始化工作,例如加载界面布局资源(setContentView)、数据初始化(findviewbyid)onRestart: 表示Activity正在被重新启动。当前activity从不可见变为可见状态时这个方法就会回调。

dev晴天的博客 1万+

【超详细】(安卓开发)使用Logcat实验对比安卓中Activity的生命周期

本文主要使用Logcat对比验证了安卓中Activity组件的生命周期

2202_75440587的博客 1125

Android安卓中Activity活动生命周期

文章目录前言活动的状态常规情况下的生命周期典型情况下的生命周期一些例外情况的生命周期异常情况下的生命周期总结 前言 Activity作为安卓四大组件之一,平常我们接触得最多得也是activity,所以很有必要详细了解一下他的详细生命周期。这篇文章定位是有一点安卓基础的,所以还完全不了解的可以先去学习一下activity。这篇文章主要是讲活动的生命周期。 活动的生命周期,人有胎儿期,青春期,老年期一...

一只修仙的猿 668

android Activity生命周期总结

前言:最开始学这个的时候,我还在想为什么要学生命周期,为什么要去了解它呢,我只要知道怎么让一个界面跳转到另一个界面不就行了吗?,举个栗子,假如你是一名医生,有一天有病人来你这里治病,你不可能就告诉它你有病,或者说你没病吧。 一:本节知识点 二:Activity生命周期状态 图片来源与来自这里 就通过一张图可能不容易理解吧,那举个栗子吧 栗子:新建一个安卓项目,在后端添加以下代码(添加日志打印,...

孤夜的博客 3851

3、从头学Android之Activity生命周期

在谈Activity生命周期之前先谈下Activity栈: Activity栈保存了已经启动并且还没有终止的所有的Activity,并且我们知道栈是遵从“后进先出”的规则,那么Activity栈同样也遵从这样的规则。 Activity的状态与其在Activity栈的位置有

90worker 6408

(十一)安卓开发中的Activity及其生命周期详解

在安卓开发中,Activity是应用的一个核心组件,它代表了用户界面中的一个屏幕。用户通过Activity与应用交互,例如点击按钮、输入文本等。每个Activity都有自己的生命周期,Android系统会根据用户操作或系统需求调用相应的生命周期方法。Activity是安卓应用的基础组件,掌握其生命周期对于开发健壮的应用至关重要。通过合理利用生命周期方法,你可以确保应用在创建、运行、暂停、停止和销毁等不同状态下都能正确响应用户操作和系统事件。

cuijiying的博客 1125

Android Activity 生命周期详解

学习android开发这么久对于activity的生命周期还没有仔细思考过,所以,我大致的把这些东西整理一下,希望通过这使自己理解的更透彻点吧! 首先看一下Activity生命周期图和它的的四个阶段  它的的四个阶段 1. 开始Activity:在这个阶段依次执行3个生命周期方法:onCreate()、onStart()和onResume()。 2. Activity失去焦点

liuyiming_的专栏 8570
上一篇: ATMS启动Activity流程 - 安卓R
下一篇: StartingWindow显示流程 - 安卓R
SSSxCCC
博客等级 码龄10年 238粉丝 74原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SSSxCCC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值