【Android 13源码分析】Activity生命周期之onCreate,onStart,onResume-2

忽然有一天,我想要做一件事:去代码中去验证那些曾经被“灌输”的理论。
                  
                  
                                           – 服装学院的IT男

本篇已收录于Activity短暂的一生系列
欢迎一起学习讨论Android应用开发或者WMS
V:WJB6995
Q:707409815

正文

在这里插入图片描述

生命周期系列:

  • Activity生命周期之onPause

  • onCreate,onStart,onResume-1

  • onCreate,onStart,onResume-2

  • Activity生命周期之onStop-1

  • Activity生命周期之onStop-2

  • Activity生命周期之onDestory

本篇为"onCreate,onStart,onResume"的第二篇,介绍应用端 onCreate,onStart,onResume 的处理

1. onCreate

onCreate 是一个新 Activity 启动的第一个生命周期。而且根据前面的铺垫,也知道了他是在 onStart 和 onResume 执行的。
对应的事务为 LaunchActivityItem

# LaunchActivityItem
    @Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
            // trace
            Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
            ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                    mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                    mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
                    client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,
                    mTaskFragmentToken);
            // 应用段处理
            client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
    @Override
    public void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        
            client.countLaunchingActivities(-1);
    }

完整的调用链如下:

LaunchActivityItem::execute
    ActivityThread::handleLaunchActivity
        ActivityThread::performLaunchActivity
            Instrumentation::newActivity      --- 创建Activity
            Activity::attach                  --- 创建Window
                Window::init
                Window::setWindowManager
            Instrumentation::callActivityOnCreate  
                Activity::performCreate
                    Activity::onCreate        --- onCreate
            ActivityClientRecord::setState    --- 设置状态为 ON_CREATE(1)

这部分的代码其实在【Activity启动流程-3】的末尾有解释,单独拎出来再看一遍。

# ActivityThread

    public Activity handleLaunchActivity(ActivityClientRecord r,
                PendingTransactionActions pendingActions, Intent customIntent) {
                    ......
                    final Activity a = performLaunchActivity(r, customIntent);
                    ......
                }
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ......
                Activity activity = null;
                try {
                    // 重点* 1. 通过Instrumentation 反射创建Activity
                    java.lang.ClassLoader cl = appContext.getClassLoader();
                    activity = mInstrumentation.newActivity(
                            cl, component.getClassName(), r.intent);
                    ......
                }
                try {
                    ......
                    // 重点* 2. 执行 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.activityConfigCallback,
                            r.assistToken, r.shareableActivityToken);
                    if (r.isPersistable()) {
                        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                    } else {
                        重点* 3. OnCreate流程
                        mInstrumentation.callActivityOnCreate(activity, r.state);
                    }
                    // 设置状态为 ON_CREATE(1)
                    r.setState(ON_CREATE);
                } ......
        ......
    }

# Instrumentation
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        // onCreate流程
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }
# Activity
    final void performCreate(Bundle icicle) {
        performCreate(icicle, null);
    }
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        ......
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            // 执行onCreate
            onCreate(icicle);
        }
        // wm_on_create_called
        EventLogTags.writeWmOnCreateCalled(mIdent, getComponentName().getClassName(),
                "performCreate");
        ......
    }

onCreate 的流程还是比较简单的,在 ActivityThread::performLaunchActivity 做了四件事:

    1. 反射创建 Activity 对象
    1. 执行 activity.attach,这里会创建Window
    1. 执行到 onCreate 生命周期
    1. 设置 ActivityClientRecord 中的状态为 ON_CREATE(1)

这里需要留意下会先执行 Activity::attach 来创建Window,然后才是后面的 Activity的onCreate。
创建 Window 的时候会创建 DecorView,有了这个 DecorView 我们在 onCreate 的时候才可以把对应的XML布局设置进去。

2. onStart

onStart 也有其对应的一个事务: StartActivityItem ,我一度以为启动 Activity 的时候也是通过这个事务来触发 onStart 的,但是实际情况我有点意外,它不是通过事务触发的,而是在执行 ResumeActivityItem 前,通过 TransactionExecutor::cycleToPath 触发的。

按下 recent 键再回到 Activity,这个时候onStart 是通过 StartActivityItem 触发的

当前分析 TransactionExecutor::cycleToPath 方法

# TransactionExecutor
    // 工具类
    private TransactionExecutorHelper mHelper = new TransactionExecutorHelper();    

    private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
            ClientTransaction transaction) {
        // 1. 获取当前ActivityClientRecord的生命周期状态值
        final int start = r.getLifecycleState();
        // log 
        if (DEBUG_RESOLVER) {
            Slog.d(TAG, tId(transaction) + "Cycle activity: "
                    + getShortActivityName(r.token, mTransactionHandler)
                    + " from: " + getStateName(start) + " to: " + getStateName(finish)
                    + " excludeLastState: " + excludeLastState);
        }
        // 2. 根据起始状态、结束状态以及是否排除最后一个状态,计算出生命周期状态变化的路径
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        // 3. 按照计算出的生命周期状态路径顺序执行相关操作
        performLifecycleSequence(r, path, transaction);
    }
    1. 获取到当前 Activity 的生命周期状态,目前是 ON_CREATE 也就是 1
    1. 通过工具类 计算出生命周期变化的路径,这个路径是啥呢, 比如说当前是 ON_CREATE(1),需要到 ON_RESUME(3), 那路径就是 [2]
    1. 根据第二步计算的路径开始执行各个生命周期

2.1 getLifecyclePath 计算生命周期切换路径

TransactionExecutor::getLifecyclePath 方法完整代码和解释都在下面了,但是我个人建议了解一下即可,大概浏览一下,留意我代码加了1,2,3 这3个重点的地方即可。

# TransactionExecutorHelper
    // 定义需要经过的生命周期路径,长度为6(毕竟一共也才7个生命周期)
    @ActivityLifecycleItem.LifecycleState
    private IntArray mLifecycleSequence = new IntArray(6);

    // start   :开始的生命周期状态
    // finish  :结束的生命周期状态
    // excludeLastState :是否移除最后一个状态
    public IntArray getLifecyclePath(int start, int finish, boolean excludeLastState) {

        // 如果开始状态或结束状态未定义,则抛出异常
        if (start == UNDEFINED || finish == UNDEFINED) {
            throw new IllegalArgumentException("Can't resolve lifecycle path for undefined state");
        }

        // 如果开始状态或结束状态是ON_RESTART,则抛出异常,因为在生命周期中不能以此状态开始或结束
        if (start == ON_RESTART || finish == ON_RESTART) {
            throw new IllegalArgumentException(
                    "Can't start or finish in intermittent RESTART state");
        }

        // 如果结束状态为PRE_ON_CREATE且开始状态不等于结束状态,则抛出异常,只能从预创建状态开始
        if (finish == PRE_ON_CREATE && start != finish) {
            throw new IllegalArgumentException("Can only start in pre-onCreate state");
        }

        // 重点* 1. 清空用于存储生命周期状态变更序列的集合
        mLifecycleSequence.clear();

        // 重点* 2. 分情况计算生命周期状态变更路径 (正常场景)
        if (finish >= start) {
            // 如果结束状态大于等于开始状态
            if (start == ON_START && finish == ON_STOP) {
                // 特殊情况:从开始到停止状态,无需经过暂停和恢复状态
                mLifecycleSequence.add(ON_STOP);
            } else {
                // 重点* 3. 普通情况:直接将中间的所有状态加入序列 (正常场景)
                for (int i = start + 1; i <= finish; i++) {
                    mLifecycleSequence.add(i);
                }
            }
        } else { // 结束状态小于开始状态,不能简单地向下循环
            if (start == ON_PAUSE && finish == ON_RESUME) {
                // 特殊情况:从暂停直接到恢复状态
                mLifecycleSequence.add(ON_RESUME);
            } else if (start <= ON_STOP && finish >= ON_START) {
                // 开始状态在ON_STOP之前且结束状态在ON_START之后的情况
                // 先转为停止状态
                for (int i = start + 1; i <= ON_STOP; i++) {
                    // 添加
                    mLifecycleSequence.add(i);
                }
                // 添加
                mLifecycleSequence.add(ON_RESTART);
                // 再转到指定结束状态
                for (int i = ON_START; i <= finish; i++) {
                    mLifecycleSequence.add(i);
                }
            } else {
                // 其他情况:需要重新启动并转到指定状态
                // 先转到销毁状态
                for (int i = start + 1; i <= ON_DESTROY; i++) {
                    // 添加
                    mLifecycleSequence.add(i);
                }
                // 再转到指定结束状态
                for (int i = ON_CREATE; i <= finish; i++) {
                    // 添加
                    mLifecycleSequence.add(i);
                }
            }
        }

        // 如果要求排除最后一个状态并且生命周期序列不为空,则移除最后一个状态
        if (excludeLastState && mLifecycleSequence.size() != 0) {
            mLifecycleSequence.remove(mLifecycleSequence.size() - 1);
        }

        // 返回计算好的生命周期状态变更序列
        return mLifecycleSequence;
    }

根据当前分析的场景,这个方法执行以下3步:

    1. 清除集合的数据,避免有脏数据影响结果
    1. 当前第一个参数是 ON_CREATE(1), 第二个参数定义在 ResumeActivityItem 下,返回值是 ON_RESUME(3),满足finish >= start的条件,所以进if语句
    1. 走 else 逻辑,最终 mLifecycleSequence 下也就一个元素 : 2 ,返回返回

2.2 performLifecycleSequence 切换Activity的生命周期

上一小节计算出需要执行的生命周期路径后,现在就要开始应用了。

# TransactionExecutor
    // 实际执行在 ActiviThread
    private ClientTransactionHandler mTransactionHandler;
    // 构造方法赋值
    public TransactionExecutor(ClientTransactionHandler clientTransactionHandler) {
        mTransactionHandler = clientTransactionHandler;
    }

    private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
            ClientTransaction transaction) {
            // 当前场景就1个元素
            final int size = path.size();
            // 开始遍历
            for (int i = 0, state; i < size; i++) {
                // 获取到状态,当前就1个元素:ON_START( 2)
                state = path.get(i);
                // 打印log
                if (DEBUG_RESOLVER) {
                    Slog.d(TAG, tId(transaction) + "Transitioning activity: "
                            + getShortActivityName(r.token, mTransactionHandler)
                            + " to state: " + getStateName(state));
                }
                switch (state) {
                    ......
                    case ON_START:
                        mTransactionHandler.handleStartActivity(r, mPendingActions,
                                null /* activityOptions */);
                        break;
                    ......
                }         
            }
        }

mTransactionHandler 在构造 TransactionExecutor 的构造方法赋值,创建对象的地方在 ActivityThread 中,传递的参数是 this,而 ActivityThread 是 ClientTransactionHandler 的子类,也就是说 mTransactionHandler 真正的实现还是在 ActivityThread。

# ActivityThread
    @Override
    public void handleStartActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, ActivityOptions activityOptions) {
            // 拿到 Activity
            final Activity activity = r.activity;
            ......
            // Start
            // 重点* 1. 执行onStart
            activity.performStart("handleStartActivity");
            // 2. 更新对应的状态
            r.setState(ON_START);
            ......
            // 重点* 3. 更新可见性,参数为true
            updateVisibility(r, true /* show */);
            mSomeActivitiesChanged = true;
            ......
        }

一共处理了3件事,其中设置状态的逻辑之前看过了,看看另外2个重点流程。

2.3 onStart 流程

# Activity
    final void performStart(String reason) {
        ......
        // 执行onStart
        mInstrumentation.callActivityOnStart(this);
        // wm_on_start_called
        EventLogTags.writeWmOnStartCalled(mIdent, getComponentName().getClassName(), reason);
        ......
        // Fragment 处理
        mFragments.dispatchStart();
        ......
    }

# Instrumentation

    public void callActivityOnStart(Activity activity) {
        activity.onStart();
    }

到这里 Activity 的 onStart 就执行了。

2.4 设置 View 可见

上一小节先执行到 onStart ,然后会设置 View 的可见性, 看一下具体代码

# ActivityThread
    private void updateVisibility(ActivityClientRecord r, boolean show) {
        // 拿到DecorView
        View v = r.activity.mDecor;
        if (v != null) {
            if (show) {
                if (!r.activity.mVisibleFromServer) {
                    r.activity.mVisibleFromServer = true;
                    mNumVisibleActivities++;
                    if (r.activity.mVisibleFromClient) {
                        // 设置 View 可见 (当前逻辑)
                        r.activity.makeVisible();
                    }
                }
            } else {
                if (r.activity.mVisibleFromServer) {
                    r.activity.mVisibleFromServer = false;
                    mNumVisibleActivities--;
                    // 隐藏View
                    v.setVisibility(View.INVISIBLE);
                }
            }
        }
    }

当前是 onStart 逻辑,也看到了方法传递的参数是 true,说明要设置可见,所以会执行 Activity::makeVisible 逻辑。

# Activity

    void makeVisible() {
        if (!mWindowAdded) { // 之前setView时已置位true
            ViewManager wm = getWindowManager();
            wm.addView(mDecor, getWindow().getAttributes());
            mWindowAdded = true;
        }
        // 设置可见
        mDecor.setVisibility(View.VISIBLE);
    }

2.5 onStart 小结

启动一个Activity 执行到 onStart 流程的分析就结束了,完整调用链如下:

TransactionExecutor::cycleToPath
    TransactionExecutorHelper::getLifecyclePath
    TransactionExecutor::performLifecycleSequence
        ClientTransactionHandler::handleStartActivity
            ActivityThread::handleStartActivity
                Activity::performStart           -- onStart
                    Instrumentation::callActivityOnStart
                        Activity::onStart
                ActivityClientRecord::setState   -- 状态设置为 ON_START
                ActivityThread::updateVisibility -- 更新View可见性
                    Activity::makeVisible
                        View::setVisibility      -- VISIBLE

如果是按多任务键(Recent)再回到 Activity 是会执行 ActivityRecord::makeActiveIfNeeded 来构建 StartActivityItem 事务处理 onStart 流程,但是后续的逻辑还是一样的

我们知道 onStart 和 onStop 是成对的, 那 onStart 会执行 View::setVisibility 设置 View 可见,那相对的在 onStop 流程是不是就会 设置 View 不可见呢?

这个疑问留到下一篇 onStop 流程解答。

当前还是继续看 onResume 的执行

3. onResume

onResume 对应事务为 ResumeActivityItem

# ResumeActivityItem

    @Override
    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
            PendingTransactionActions pendingActions) {
            // Trace
            Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
            // 应用端处理
            client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
                    "RESUME_ACTIVITY");
            Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

    @Override
    public void postExecute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        // TODO(lifecycler): Use interface callback instead of actual implementation.
        ActivityClient.getInstance().activityResumed(token, client.isHandleSplashScreenExit(token));
    }

    @Override
    public int getTargetState() {
        return ON_RESUME;
    }

调用链如下:

ResumeActivityItem::execute
    ActivityThread::handleResumeActivity
        ActivityThread::performResumeActivity   
            Activity::performResume     
                Instrumentation::callActivityOnResume
                    Activity::onResume           -- onResume
                ActivityClientRecord::setState   -- ON_RESUME
        WindowManagerImpl::addView               -- 创建ViewRootImpl
            WindowManagerGlobal::addView   
                ViewRootImpl::setView            -- 与WMS通信与WMS通信触发窗口的显示逻辑

开始撸代码。

# ActivityThread
    public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
            boolean isForward, String reason) {
        ......
        // 触发onResume
        if (!performResumeActivity(r, finalStateRequest, reason)) {
            return;
        }
        ......
        // 拿到activity
        final Activity a = r.activity;
        ......
        if (r.window == null && !a.mFinished && willBeVisible) {
            // 将本地的window设置到activityRecord中
            r.window = r.activity.getWindow();
            // 获取DecorView
            View decor = r.window.getDecorView();
            // 设置不可见  在后面调用Activity::makeVisible会设为可见
            decor.setVisibility(View.INVISIBLE);
            ViewManager wm = a.getWindowManager();
            // 获取参数
            WindowManager.LayoutParams l = r.window.getAttributes();
            // DecorView设置给Activity
            a.mDecor = decor;
            // 设置Activity的windowType,注意这个type,才是应用的窗口类型
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            ......
            if (a.mVisibleFromClient) {
                if (!a.mWindowAdded) {
                    // 重点:执行addView,并设置mWindowAdded=true
                    a.mWindowAdded = true;
                    wm.addView(decor, l);
                } else {
                    a.onWindowAttributesChanged(l);
                }
            }

        } else if (!willBeVisible) {
            if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
            r.hideForNow = true;
        }
        ......
        r.nextIdle = mNewActivities;
        mNewActivities = r;
        // stop 逻辑的触发
        if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
        Looper.myQueue().addIdleHandler(new Idler());
    }

当前分析 onResume 生命周期,所以只看 performResumeActivity 方法就好。

# ActivityThread

    @VisibleForTesting
    public boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
            String reason) {
            // log
            if (localLOGV) {
                Slog.v(TAG, "Performing resume of " + r + " finished=" + r.activity.mFinished);
            }
                ......
                // 触发 onResume
                r.activity.performResume(r.startsNotResumed, reason);
                // 设置状态
                r.setState(ON_RESUME);
                ......
        }
# Activity
    final void performResume(boolean followedByPause, String reason) {
            // trace
            if (Trace.isTagEnabled(Trace.TRACE_TAG_WINDOW_MANAGER)) {
                Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "performResume:"
                        + mComponent.getClassName());
            }
            ......
            // 主流程
            mInstrumentation.callActivityOnResume(this);
            // wm_on_resume_called
            EventLogTags.writeWmOnResumeCalled(mIdent, getComponentName().getClassName(), reason);
            ......
            // Fragments 处理
            mFragments.dispatchResume();
            ......
    }

流程和其他的一样,也是先通过 Instrumentation 然后又回到 Activity 处理,然后打印另一个 events 日志。

# Instrumentation
    public void callActivityOnResume(Activity activity) {
        activity.mResumed = true;
        activity.onResume();
    }

4. 总结

SourceActivity 在启动过程中会执行的3个生命周期已经分析完了,当前分析的场景下有以下几个点:

    1. 这3个生命周期的执行的连续的,
    1. onStart 原来这个场景下不是通过事务执行的
    1. 知道了 Activity 生命周期事务跨进程处理方式
    1. DecorView 的可见性是在 onStart 设置的
    1. 执行 onResume 的时候会触发窗口的添加显示,从严格意义上说,执行 onResume 的时候并不意味着手机屏幕上就有UI数据了。(但是不那么严谨思考的话,正常情况下,onResume 执行了差不多窗口也就显示了)

关于 events 日志的整理如下:

    1. wm_restart_activity 的触发在 ActivityTaskSupervisor::realStartActivityLocked 方法构建2个事务的时候,表示 SystemService 端要真正触发 TargetActivity 启动
    1. wm_on_create_called 的触发在 Activity::performCreate 方法,表示TargetActivity端执行 onCreate
    1. wm_on_start_called 的触发在 Activity::performStart 方法,表示TargetActivity端执行 onStart
    1. wm_on_resume_called 的触发在 Activity::performResume 方法,表示TargetActivity端执行 onResume

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/887743.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微服务Sleuth解析部署使用全流程

目录 1、Sleuth链路追踪 1、添加依赖 2、修改日志配置文件 3、测试 2、zipkin可视化界面 1、docker安装 2、添加依赖 3、修改配置文件 4、查看页面 5、ribbon配置 1、Sleuth链路追踪 sleuth是链路追踪框架&#xff0c;用于在微服务架构下开发&#xff0c;各个微服务之…

[水墨:创作周年纪念] 特别篇!

本篇是特别篇&#xff01;&#xff01; 个人主页水墨不写bug // _ooOoo_ // // o8888888o // // 88" . "88 …

GO网络编程(二):客户端与服务端通信【重要】

本节是新知识&#xff0c;偏应用&#xff0c;需要反复练习才能掌握。 目录 1.C/S通信示意图2.服务端通信3.客户端通信4.通信测试5.进阶练习&#xff1a;客户端之间通信 1.C/S通信示意图 客户端与服务端通信的模式也称作C/S模式&#xff0c;流程图如下 其中P是协程调度器。可…

《CUDA编程》5.获得GPU加速的关键

从本章起&#xff0c;将关注CDUA程序的性能&#xff0c;即执行速度 1 用CUDA事件计时 在前几章中&#xff0c;使用的是C的<time.h>库进行程序运行计时&#xff0c;CUDA也提供了一种基于CUDA event的计时方式&#xff0c;用来给一段CUDA代码进行计时&#xff0c;这里只介…

系统架构设计师-下午案例题(2021年下半年)

1.试题一(共25分) 阅读以下关于软件架构设计与评估的叙述在答题纸上回答问题1和问题2。 【说明】某公司拟开发一套机器学习应用开发平台支持用户使用浏览器在线进行基于机器学习的智能应用开发活动。该平台的核心应用场景是用户通过拖拽算法组件灵活定义机器学习流程&#xf…

【含开题报告+文档+PPT+源码】基于SSM + Vue的养老院管理系统【包运行成功】

开题报告 随着社会的发展和经济的进步&#xff0c;人口老龄化问题逐渐凸显。统计数据显示&#xff0c;全球范围内的老龄人口比例正在逐年上升&#xff0c;养老需求也随之增长。养老院作为提供专业养老服务的机构&#xff0c;承担着照料老人、提供医疗保健和社交活动等责任。传…

什么是pip? -- Python 包管理工具

前言 不同的编程语言通常都有自己的包管理工具&#xff0c;这些工具旨在简化项目的依赖管理、构建过程和开发效率&#xff0c;同时促进代码的复用和共享。每个包管理工具都有其独特的特点和优势&#xff0c;开发者可以根据自己的编程语言和项目需求选择合适的包管理工具。 pip是…

车辆重识别(2021ICML改进的去噪扩散概率模型)论文阅读2024/9/29

所谓改进的去噪扩散概率模型主要改进在哪些方面&#xff1a; ①对数似然值的改进 通过对噪声的那个方差和T进行调参&#xff0c;来实现改进。 ②学习 这个参数也就是后验概率的方差。通过数据分析&#xff0c;发现在T非常大的情况下对样本质量几乎没有影响&#xff0c;也就是说…

TIM的PWM模式

定时器的工作流程: 定时器对时钟传来的脉冲次数计数&#xff0c;并且在次数到达范围值时触发中断。如向下计数模式时为0&#xff0c;向上计数为达到自动重装载计时器的值时触发中断。 四个输出比较单元 更改占空比的函数 STM32里面的定时器有多个定时器。 如TIM1、TIM2…

k8s 之安装metrics-server

作者&#xff1a;程序那点事儿 日期&#xff1a;2024/01/29 18:25 metrics-server可帮助我们查看pod的cpu和内存占用情况 kubectl top po nginx-deploy-56696fbb5-mzsgg # 报错&#xff0c;需要Metrics API 下载 Metrics 解决 wget https://github.com/kubernetes-sigs/metri…

nginx 负载均衡1

遇到的问题 大型网站都要面对庞大的用户量&#xff0c;高并发&#xff0c;海量数据等挑战。为了提升系统整体的性能&#xff0c;可以采用垂直扩展和水平扩展两种方式。 垂直扩展&#xff1a;在网站发展早期&#xff0c;可以从单机的角度通过增加硬件处理能力&#xff0c;比如 C…

LeetCode讲解篇之239. 滑动窗口最大值

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们维护一个长度为k的窗口&#xff0c;然后窗口从数组最左边一直移动到最右边&#xff0c;记录过程中窗口中的最大值&#xff0c;就是答案 我们每次查询长度为k的窗口最大值是什么时间复杂度是O(k)的&#xff0…

黑神话:仙童,数据库自动反射魔法棒

黑神话&#xff1a;仙童&#xff0c;数据库自动反射魔法棒 Golang 通用代码生成器仙童发布了最新版本电音仙女尝鲜版十一及其介绍视频&#xff0c;视频请见&#xff1a;https://www.bilibili.com/video/BV1ET4wecEBk/ 此视频介绍了使用最新版的仙童代码生成器&#xff0c;将 …

使用 Python 遍历文件夹

要解决这个问题&#xff0c;使用 Python 的标准库可以很好地完成。我们要做的是遍历目录树&#xff0c;找到所有的 text 文件&#xff0c;读取内容&#xff0c;处理空行和空格&#xff0c;并将处理后的内容合并到一个新的文件中。 整体思路&#xff1a; 遍历子目录&#xff1…

计算机毕业设计 基于Hadoop的智慧校园数据共享平台的设计与实现 Python 数据分析 可视化大屏 附源码 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

国外电商系统开发-运维系统拓扑布局

点击列表中设备字段&#xff0c;然后定位到【拓扑布局】中&#xff0c;可以看到拓扑发生了变化 再回头&#xff0c;您再次添加一个服务器到系统中&#xff0c;并且选择该服务器的连接节点为您刚才创建的“SDN路由器”&#xff0c;保存后&#xff0c;您可以看到这个服务器连接着…

RabbbitMQ篇(环境搭建 - 下载 安装)(持续更新迭代)

目录 一、Windows 1. 下载安装程序 2. 安装配置erlang 3. 安装rabbitMQ 4. 验证 二、Linux 1. 下载rpm包 1.1. 下载Erlang的rpm包 1.2. 下载socat的rpm包 1.3. 下载RabbitMQ的rpm包 2. 安装 2.1. 安装Erlang 2.2. 安装socat 2.3. 安装RabbitMQ 3. 启动RabbitMQ服…

小程序原生-利用setData()对不同类型的数据进行增删改

1. 声明和绑定数据 wxml文件 <view> {{school}} </view> <view>{{obj.name}}</view> <view id"{{id}}" > 绑定属性值 </view> <checkbox checked"{{isChecked}}"/> <!--算数运算--> <view>{{ id …

数理统计(第1章第2节:一些常用的抽样分布)

目录 统计量的概率分布称为“抽样分布” 1. 正态母体的子样平均数的抽样分布 正态分布 2. 卡方分布 3. t分布 4. F分布 5. 例题 6. 总结 统计量的概率分布称为“抽样分布” 1. 正态母体的子样平均数的抽样分布 正态分布 若随机变量X的概率密度为&#xff1a; 则称X服…

Qt开发技巧(九)去掉切换按钮,直接传样式文件,字体设置,QImage超强,巧用Qt的全局对象,信号槽断连,低量数据就用sqlite

继续讲一些Qt开发中的技巧操作&#xff1a; 1.去掉切换按钮 QTabWidget选项卡有个自动生成按钮切换选项卡的机制&#xff0c;有时候不想看到这个烦人的切换按钮&#xff0c;可以设置usesScrollButtons为假&#xff0c;其实QTabWidget的usesScrollButtons属性最终是应用到QTabWi…