首页 > 其他分享 >ActivityManagerService app状态流转(4)

ActivityManagerService app状态流转(4)

时间:2024-09-18 21:50:18浏览次数:3  
标签:transaction app null 流转 Activity ClientTransaction ActivityManagerService final

ActivityManagerService app状态流转

简述

做过应用开发应该会对Activity的生命周期很熟悉,Activity有onCreate、onStart、onResume…等生命周期,前面在介绍Activity启动流程时,我们提到过SystemServer会通过ClientTransaction来通知app更新生命周期状态变化,以前SystemServer和app会来回通信,onCreate、onResume都会通过binder回调app侧,而新版本的Android在这里做了一定的优化,SystemServer只会通过一次binder通知app要达到的最终状态,app侧会自己控制状态流转到目标状态,这样就减少了binder通信的次数。

我们就从启动Activity的流程中SystemServer通知app侧resume来了解一下这个流程。

app Activity启动流程resume

在这里插入图片描述

1.1 ActivityTaskSupervisor.realStartActivityLocked
我们就从realStartActivityLocked SystemServer通知app Resume开始。

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

        // ...
        try {
            // ... 
            final ClientTransaction clientTransaction = ClientTransaction.obtain(
                    proc.getThread(), r.token);

            final boolean isTransitionForward = r.isTransitionForward();
            final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();

            final int deviceId = getDeviceIdForDisplayId(r.getDisplayId());
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                    System.identityHashCode(r), r.info, 
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), deviceId,
                    r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
                    proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
                    results, newIntents, r.takeOptions(), isTransitionForward,
                    proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
                    r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));

            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
                // 这里是启动流程,我们看唤醒的逻辑。这里创建了ResumeActivityItem
                lifecycleItem = ResumeActivityItem.obtain(isTransitionForward,
                        r.shouldSendCompatFakeFocus());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            // clientTransaction记录对应的操作Item
            clientTransaction.setLifecycleStateRequest(lifecycleItem);
            // 详见1.2
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);
            // ... 
        }
        // ...
}

1.2 ClientLifecycleManager.scheduleTransaction
调用了ClientTransaction.schedule

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    final IApplicationThread client = transaction.getClient();
    // 详见1.3
    transaction.schedule();
    if (!(client instanceof Binder)) {
        transaction.recycle();
    }
}

1.3 ClientTransaction.schedule
Client是App的binder引用,这里就会通过binder调用到app侧了,并且把ClientTransaction全部传过去

public void schedule() throws RemoteException {
    // 这里的Client是App的binder引用,这里就会通过binder调用到app侧了,并且把ClientTransaction全部传过去。
    // 详见1.4
    mClient.scheduleTransaction(this);
}

1.4 ApplicationThread.scheduleTransaction
这里已经在app侧。

public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    // 详见1.5
    ActivityThread.this.scheduleTransaction(transaction);
}

1.5 ClientTransactionHandler.scheduleTransaction
ActivityThread是ClientTransactionHandler的子类。

void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    // 处理消息的地方详见1.6
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

1.6 ActivityThread.H.handleMessage
获取SystemServer传过来的ClientTransaction,

public void handleMessage(Message msg) {
    // ...
    case EXECUTE_TRANSACTION:
        final ClientTransaction transaction = (ClientTransaction) msg.obj;
        mTransactionExecutor.execute(transaction);
        if (isSystem()) {
            transaction.recycle();
        }
        break;
    // ...
}

1.7 TransactionExecutor.execute
这里ClientTransaction传递ClientTransactionItem有两种方式,一种是addCallback,另一种是setLifecycleStateRequest,两种方式做的事都差不多,只不过addCallback用于记录中间操作,LifecycleStateRequest用于记录最终目标状态。
例如我们要启动一个Activity,则会在Callback里添加LaunchActivityItem,然后在LifecycleStateRequest中配置ResumeActivityItem,表示要先操作LaunchActivityItem创建启动Activity,然后启动的Activity最终状态要流转至resume状态。
这里先通过ClientTransaction里ActivityToken确认Activity是否创建,以及如果未创建并且要销毁,就可以直接返回什么都不做。
否则会先处理callbacks,然后再处理executeLifecycleState。

public void execute(ClientTransaction transaction) {
    if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
    // 获取ClientTransaction里的ActivityToken,可以对应到Activity
    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) {
                // 如果是destroyItem,现在就要进行destory,删除activitiesToBeDestroyed里的记录
                activitiesToBeDestroyed.remove(token);
            }
            if (mTransactionHandler.getActivityClient(token) == null) {
                // 如果Activity没有create,现在是destroy操作,就直接什么都不做。
                Slog.w(TAG, tId(transaction) + "Skip pre-destroyed transaction:\n"
                        + transactionToString(transaction, mTransactionHandler));
                return;
            }
        }
    }

    if (DEBUG_RESOLVER) Slog.d(TAG, transactionToString(transaction, mTransactionHandler));
    // 处理Callbacks,详见1.7.1
    executeCallbacks(transaction);
    // 处理LifecycleStateRequest,详见1.8
    executeLifecycleState(transaction);
    mPendingActions.clear();
    if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}

1.7.1 TransactionExecutor.executeCallbacks
主要是调用每一个callback等execute和postExecute,在调用之前会判断是否需要先将Activity预先流转到某个状态,如果需要会通过cycleToPath流转,cycleToPath后面再看。

public void executeCallbacks(ClientTransaction transaction) {
    final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
    if (callbacks == null || callbacks.isEmpty()) {
        // 如果没有callbacks,直接返回
        return;
    }
    if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");

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

    // 这里获取一下最终状态
    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();

        if (item.shouldHaveDefinedPreExecutionState()) {
            // 这里会获取item预先需要的状态,LaunchActivityItem这里没有预先要求的状态,所以不会走cycleToPath
            final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                    item.getPostExecutionState());
            if (closestPreExecutionState != UNDEFINED) {
                // 如果有需要预先流转的状态,则先通过cycleToPath流转至目标状态。
                cycleToPath(r, closestPreExecutionState, transaction);
            }
        }
        // 执行item对应的操作,详见1.7.2 
        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);
        if (r == null) {
            r = mTransactionHandler.getActivityClient(token);
        }

        if (postExecutionState != UNDEFINED && r != null) {
            // 如果最终状态和callbacks状态不同,这里不将状态转换到最终状态。而是等到executeLifecycleState时候进行转换。
            final boolean shouldExcludeLastTransition =
                    i == lastCallbackRequestingState && finalState == postExecutionState;
            cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
        }
    }
}

1.7.2 LaunchActivityItem.execute
构造ActivityClientRecord,每个Activtiy在端侧都会有一个ActivityClientRecord,在后台时Activity被回收的情况这个ActivityClientRecord不会被回收,记录Activity的关键状态信息等。
调用handleLaunchActivity。

public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
    // app侧每个Activity都会有一个ActivityClientRecord,就是这里构建的
    // 在后台的时候,activity会被回收,但是ActivityClientRecord不会。
    ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
            mOverrideConfig, mReferrer, mVoiceInteractor, mState, mPersistentState,
            mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
            client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,
            mTaskFragmentToken);
    // 详见1.7.3
    client.handleLaunchActivity(r, pendingActions, mDeviceId, null /* customIntent */);
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

1.7.3 ActivityThread.handleLaunchActivity
调用performLaunchActivity创建Activity。

public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, int deviceId, Intent customIntent) {
    // ...一些环境初始化
    // 详见1.7.4
    final Activity a = performLaunchActivity(r, customIntent);

    if (a != null) {
        // 更新Activity Configuration配置
        r.createdConfig = new Configuration(mConfigurationController.getConfiguration());
        reportSizeConfigurations(r);
        if (!r.activity.mFinished && pendingActions != null) {
            pendingActions.setOldState(r.state);
            pendingActions.setRestoreInstanceState(true);
            pendingActions.setCallOnPostCreate(true);
        }
    } else {
        // 如果performLaunchActivity没有成功创建Activity,直接调用finish周期
        ActivityClient.getInstance().finishActivity(r.token, Activity.RESULT_CANCELED,
                null /* resultData */, Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
    }

    return a;
}

1.7.4 ActivityThread.performLaunchActivity
这个方法是真正做创建Activity的方法。
创建Context、Resources。
通过反射构建Activity。
调用makeApplicationInner,如果首次调用makeApplicationInner,会构造Application。
然后会调用activity.attach初始化了一些activity里面的变量,同时构建了PhoneWindow。honeWindow是用于管理Activity的窗口以及ui相关的逻辑的,里面会构造DecorView来包含应用的UI。
通过callActivityOnCreate调用Activity的onCreate的生命周期。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ActivityInfo aInfo = r.activityInfo;

    // 获取packageInfo
    if (r.packageInfo == null) {
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, mCompatibilityInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }

    ComponentName component = r.intent.getComponent();
    if (component == null) {
        // 获取ComponentName
        component = r.intent.resolveActivity(
            mInitialApplication.getPackageManager());
        r.intent.setComponent(component);
    }

    if (r.activityInfo.targetActivity != null) {
        component = new ComponentName(r.activityInfo.packageName,
                r.activityInfo.targetActivity);
    }

    // 根据ActivityClientRecord里面的信息,如packageInfo,displayId等构造Context,同时还会构造Resources。
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        // 这里会通过反射构造Activity等实例。
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
                appContext.getAttributionSource());
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
        // ...
    }

    try {
        // 如果是首次调用,会构造Application,否则直接返回之前构造的Application
        Application app = r.packageInfo.makeApplicationInner(false, mInstrumentation);

        // 将ActivityClientRecord记录。
        synchronized (mResourcesManager) {
            mActivities.put(r.token, r);
        }

        if (activity != null) {
            // ...
            // attach主要是初始化了一些activity里面的变量,同时构建了PhoneWindow。
            // PhoneWindow是用于管理Activity的窗口以及ui相关的逻辑的,里面会构造DecorView来包含应用的UI
            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.activityConfigCallback,
                    r.assistToken, r.shareableActivityToken);

            // ...
            // 这里callActivityOnCreate就是App侧Activity onCreate回调的生命周期。
            r.activity = activity;
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            // ...
            r.mLastReportedWindowingMode = config.windowConfiguration.getWindowingMode();
        }
        // 更新ActivityClientRecord状态
        r.setState(ON_CREATE);

    } catch (SuperNotCalledException e) {
        // ...
    } catch (Exception e) {
        // ...
    }

    return activity;
}

1.8 TransactionExecutor.executeLifecycleState

private void executeLifecycleState(ClientTransaction transaction) {
    final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
    if (lifecycleItem == null) {
        return;
    }

    final IBinder token = transaction.getActivityToken();
    final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
    
    if (r == null) {
        // ActivityClientRecord为null直接返回。
        return;
    }

    // 调用cycleToPath流转状态。详见1.9
    cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);

    // 这个和前面relaunch类似,就是执行onResume
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
    lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}

1.9 TransactionExecutor.cycleToPath

private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
        ClientTransaction transaction) {
    // 获取起始状态。
    final int start = r.getLifecycleState();
    // 根据出事状态和最终状态,获取流转状态序列
    // 例如这里最终状态是resume,前面执行到了onCreate,这里返回的序列就是onStart和onResume
    final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
    // 详见1.10
    performLifecycleSequence(r, path, transaction);
}

1.10 TransactionExecutor.performLifecycleSequence
不同状态流转,最终都会调用mTransactionHandler.handleXXX,handleLaunchActivity前面已经看过.
handleResumeActivity回回调onResume,同时会通过addView将DecorView添加到WMS,后续才会渲染显示,做应用开发的知道app只有在resume后才会显示,就是这个逻辑。

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,
                        Context.DEVICE_ID_INVALID, null /* customIntent */);
                break;
            case ON_START:
                mTransactionHandler.handleStartActivity(r, mPendingActions,
                        null /* activityOptions */);
                break;
            case ON_RESUME:
                mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
                        r.isForward, false /* shouldSendCompatFakeFocus */,
                        "LIFECYCLER_RESUME_ACTIVITY");
                break;
            case ON_PAUSE:
                mTransactionHandler.handlePauseActivity(r, false /* finished */,
                        false /* userLeaving */, 0 /* configChanges */,
                        false /* autoEnteringPip */, 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);
        }
    }
}

小结

SystemServer通过scheduleTransaction来通知app,更新app侧生命周期状态。
通过addCallback添加Activity中间流程,setLifecycleStateRequest配置最终状态。
app侧收到Transcation的Callback和LifecycleStateRequest,进行对应的生命周期流转以及回调。

标签:transaction,app,null,流转,Activity,ClientTransaction,ActivityManagerService,final
From: https://blog.csdn.net/weixin_43833152/article/details/142344545

相关文章

  • ActivityManagerService Activity的启动流程(2)
    ActivityManagerServiceActivity的启动流程简述提到ActivityManagerService,最重要的流程之一就是启动Activity了。这个流程比较复杂:启动activity的调用链很长。业务逻辑很多,activity启动有很多flag,例如FLAG_ACTIVITY_NEW_TASK,FLAG_ACTIVITY_CLEAR_TOP等等。需要在app进......
  • 当前标识(IIS APPPOOL\.NET v4.5)没有对“C:\Windows\Microsoft.NET\Framework64
    当前标识(IISAPPPOOL\.NETv4.5)没有对“C:\Windows\Microsoft.NET\Framework64\v4.0.30319\TemporaryASP.NETFiles”的写访问权限。初学者在使用ISS创建网站时是不是也遇到过类似的问题,这可能是执行当前Web请求期间生成了未经处理的异常,主要就是设置对TemporaryASP.NE......
  • uniapp utils
    import{sendUpdataUrl,IMG_URL}from"/http";importmomentfrom'moment'importCryptoJSfrom'crypto-js';constStorage={/***设置缓存*@param{string}key-键*@param{any}value-值*@param{string}exp......
  • 基于django+vue个人健康管理APPapp端【开题报告+程序+论文】-计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景在快节奏的现代生活中,健康已成为人们日益关注的焦点。随着科技的飞速发展,智能手机普及率的大幅提升,以及大数据、人工智能等技术的广泛应用......
  • 拍卖转拍商城软件app开发
    竞拍转拍互助软件app开发,viper299基于java“臻宝”书画竞拍系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署本源码技术栈:项目架构:B/S架构开发语言:Java语言开发软件:ideaeclipse前端技术:Layui、HTML、CSS、JS、JQuery等技术后端技术:JAVA运行环境:Win10、JDK1.8最......
  • EF AutoMapper映射后取值
      publicasyncTask<PagedResult<ClientInfoDTO>>GetPageAsync(ClientQueryDTOq){varquery=awaitthis._clientService.GetQueryableAsync(q);vartotal=query.DeferredCount().FutureValue();switch(q.OrderBy)......
  • App结合3D形象的技术实现选择
    在为App添加3D人物交互效果时,可以采用多种技术,具体选择取决于你的目标平台(iOS、Android、跨平台)以及项目的复杂性和需求。以下是几种常用技术及其特点:游戏引擎技术游戏引擎提供了强大的3D图形渲染和交互功能,是实现3D人物交互效果的主流选择。Unity特点:跨平台:Unity支持iOS、Android......
  • 使用call、apply和bind改变函数执行时的上下文
    使用call、apply和bind都能够是函数的上下文发生改变,那我们来具体看看这记者之间的区别吧。call方法:语法:call([thisObj[,arg1[,arg2[,  [,.argN]]]]])定义:调用一个对象的一个方法,以另一个对象替换当前对象。说明:call方法可以用来代替另一个对象调用一个方法。call方法......
  • 2024短剧系统开发,付费短剧小程序app源码教程,分销功能讲解搭建上线
    短剧系统技术栈前端:vue3+uniapp 后端:php数据库:mysql服务器环境:centos7.6宝塔php7.4MySQL5.7一、短剧系统功能短剧用户端:小程序、抖音小程序、快手小程序、APP、z付宝小程序系统用户端详细功能:付费点播、会员等级、会员分销、VIP、积分商城、卡......
  • uni-app生命周期
    目录一、页面生命周期1、onLoad【常用】2、onShow【常用】3、onReady【常用】4、onHide【常用】5、onPullDownRefresh【常用】6、onReachBottom【常用】二、应用生命周期1、onLaunch【常用】2、onShow【常用】3、onHide【常用】三、组件生命周期1、beforeCreate......