返回顶部
首页 > 资讯 > 精选 >Android ViewModelScope怎么自动取消协程
  • 466
分享到

Android ViewModelScope怎么自动取消协程

2023-07-02 15:07:56 466人浏览 泡泡鱼
摘要

本文小编为大家详细介绍“Android ViewModelScope怎么自动取消协程”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android ViewModelScope怎么自动取消协程”文章能帮助大家解决疑惑,下

本文小编为大家详细介绍“Android ViewModelScope怎么自动取消协程”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android ViewModelScope怎么自动取消协程”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

先看一下 ViewModel 中的 ViewModelScope 是何方神圣

val ViewModel.viewModelScope: CoroutineScope        get() {            val scope: CoroutineScope? = this.getTag(JOB_KEY)            if (scope != null) {                return scope            }            return setTagIfAbsent(JOB_KEY,                CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main.immediate))        }

可以看到这个是一个扩展方法,

再点击 setTagIfAbsent 方法进去

 <T> T setTagIfAbsent(String key, T newValue) {        T previous;        synchronized (mBaGofTags) {            previous = (T) mBagOfTags.get(key);//第一次肯定为null            if (previous == null) {                mBagOfTags.put(key, newValue);//null 存储            }        }        T result = previous == null ? newValue : previous;        if (mCleared) {//判断是否已经clear了            // It is possible that we'll call close() multiple times on the same object, but            // Closeable interface requires close method to be idempotent:            // "if the stream is already closed then invoking this method has no effect." (c)            closeWithRuntimeException(result);        }        return result;    }

可以看到 这边 会把 我们的 ViewModel 存储到 ViewModel 内的 mBagOfTags 中

这个 mBagOfTags 是

    private final Map<String, Object> mBagOfTags = new HashMap<>();

这个时候 我们 viewModel 就会持有 我们 viewModelScope 的协程 作用域了。那..这也只是 表述了 我们 viewModelScope 存在哪里而已,什么时候清除呢?

先看一下 ViewModel 的生命周期:

Android ViewModelScope怎么自动取消协程

可以看到 ViewModel 的生命周期 会在 Activity onDestory 之后会被调用。那...具体哪里调的?

翻看源码可以追溯到 ComponentActivity 的默认构造器内

 public ComponentActivity() {             getLifecycle().addObserver(new LifecycleEventObserver() {            @Override            public void onStateChanged(@NonNull LifecycleOwner source,                    @NonNull Lifecycle.Event event) {                if (event == Lifecycle.Event.ON_DESTROY) {                    if (!isChanginGConfigurations()) {                        getViewModelStore().clear();                    }                }            }        });  }

可以看到内部会通对 Lifecycle 添加一个观察者,观察当前 Activity 的生命周期变更事件,如果走到了 Destory ,并且 本次 Destory 并非由于配置变更引起的,才会真正调用 ViewModelStore 的 clear 方法。

跟进 clear 方法看看:

public class ViewModelStore {    private final HashMap<String, ViewModel> mMap = new HashMap<>();        public final void clear() {        for (ViewModel vm : mMap.values()) {            vm.clear();        }        mMap.clear();    }}

可以看到这个 ViewModelStore 内部实现 用 HashMap 存储 ViewModel

于是在 clear 的时候,会逐个遍历调用 clear方法,再次跟进 ViewModel 的 clear 方法

 @MainThread    final void clear() {        mCleared = true;        // Since clear() is final, this method is still called on mock objects        // and in those cases, mBagOfTags is null. It'll always be empty though        // because setTagIfAbsent and getTag are not final so we can skip        // clearing it        if (mBagOfTags != null) {            synchronized (mBagOfTags) {                for (Object value : mBagOfTags.values()) {                    // see comment for the similar call in setTagIfAbsent                    closeWithRuntimeException(value);                }            }        }        onCleared();    }

可以发现我们最初 存放 viewmodelScope 的 mBagOfTags

这里面的逻辑 就是对 mBagOfTags 存储的数据 挨个提取出来并且调用 closeWithRuntimeException

跟进 closeWithRuntimeException:

 private static void closeWithRuntimeException(Object obj) {        if (obj instanceof Closeable) {            try {                ((Closeable) obj).close();            } catch (IOException e) {                throw new RuntimeException(e);            }        }    }

该方法内会逐个判断 对象是否实现 Closeable 如果实现就会调用这个接口的 close 方法,

再回到最初 我们 viewModel 的扩展方法那边,看看我们 viewModelScope 的真正面目

internal class CloseableCoroutineScope(context: CoroutineContext)     : Closeable, CoroutineScope {    override val coroutineContext: CoroutineContext = context    override fun close() {        coroutineContext.cancel()    }}

可以明确的看到 我们的 ViewModelScope 实现了 Closeable 并且充写了 close 方法,

close 方法内的实现 会对 协程上下文进行 cancel。

至此我们 可以大致整理一下:

  • viewModelScope 是 ViewModel 的扩展成员,该对象是 CloseableCoroutineScope,并且实现了 Closeable 接口

  • ViewModelScope 存储在 ViewModel 的 名叫 mBagOfTags 的HashMap中 啊

  • ViewModel 存储在 Activity 的 ViewModelStore 中,并且会监听 Activity 的 Lifecycle 的状态变更,在ON_DESTROY 且 非配置变更引起的事件中 对 viewModelStore 进行清空

  • ViewModelStore 清空会对 ViewModelStore 内的所有 ViewModel 逐个调用 clear 方法。

  • ViewModel的clear方法会对 ViewModel的 mBagOfTags 内存储的对象进行调用 close 方法(该对象需实现Closeable 接口)

  • 最终会会调用 我们 ViewModelScope 的实现类 CloseableCoroutineScope 的 close 方法中。close 方法会对协程进行 cancel。

读到这里,这篇“Android ViewModelScope怎么自动取消协程”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网精选频道。

--结束END--

本文标题: Android ViewModelScope怎么自动取消协程

本文链接: https://lsjlt.com/news/342605.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Android ViewModelScope怎么自动取消协程
    本文小编为大家详细介绍“Android ViewModelScope怎么自动取消协程”,内容详细,步骤清晰,细节处理妥当,希望这篇“Android ViewModelScope怎么自动取消协程”文章能帮助大家解决疑惑,下...
    99+
    2023-07-02
  • 一文了解Android ViewModelScope 如何自动取消协程
    先看一下 ViewModel 中的 ViewModelScope 是何方神圣 val ViewModel.viewModelScope: Co...
    99+
    2024-04-02
  • Android取消EditText自动获取默认焦点
    最近在通讯录新建联系人=中,一进入一个页面, EditText默认就会自动获取焦点,很是郁闷, 如何让EditText不自动获取焦点? 那么如何取消这个默认行为呢? 在网上找了...
    99+
    2022-06-06
    edittext 默认 Android
  • win10怎么取消自动休眠
    在win10中取消自动休眠的方法:1.右键点击鼠标,选择“个性化”选项;2.进入锁屏界面选项;3.点击“屏幕保护程序设置”;4.点击更改电源设置选项;5.点击“选择关闭显示器事件”选项;6.将关闭显示器时间设置为“从不”并保存;具体步骤如下...
    99+
    2024-04-02
  • centos7怎么取消自动锁屏
    这篇文章主要介绍“centos7怎么取消自动锁屏”,在日常操作中,相信很多人在centos7怎么取消自动锁屏问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”centos7怎么取消自动锁屏”的疑惑有所帮助!接下来...
    99+
    2023-06-10
  • ubuntu怎么取消自动休眠
    要取消Ubuntu的自动休眠功能,可以按照以下步骤进行操作:1. 打开“设置”应用程序。可以在左上角的活动图标中搜索并打开它,或者通...
    99+
    2023-08-31
    ubuntu
  • win10怎么取消自动登录
    要取消Windows 10的自动登录功能,请按照以下步骤操作:1. 打开“运行”对话框。可以按下Win键 + R来快速打开。2. 输...
    99+
    2023-09-01
    win10
  • ultraedit自动换行怎么取消
    今天小编给大家分享一下ultraedit自动换行怎么取消的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。ultraedit取消...
    99+
    2023-07-01
  • navicat怎么取消自动更新
    通过取消选中 navicat “更新”选项卡中的“自动检查更新”复选框,您可以禁用 navicat 的自动更新功能。 如何取消 Navicat 自动更新 取消 Navicat 自动更新...
    99+
    2024-04-24
    navicat
  • 电脑怎么取消自动休眠
    这篇文章主要为大家展示了“电脑怎么取消自动休眠”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“电脑怎么取消自动休眠”这篇文章吧。取消电脑自动休眠方法:打开控制面板,随后选择“系统和安全”进入。开始...
    99+
    2023-06-27
  • 苹果怎么取消自动续费
    苹果取消自动续费的方法:1、打开“App Store”,在底部点击“Apple ID”;2、在弹出的选项中选择“查看Apple ID”,并输入Apple ID密码;3、在“账户”页面中向下滑动,找到“订阅”;4、点击“订阅”,进入订阅管理页...
    99+
    2023-08-14
  • Android取消EditText自动获取焦点默认行为
    在项目中,一进入一个页面, EditText默认就会自动获取焦点。 那么如何取消这个默认行为呢? 在网上找了好久,有点 监听软键盘事件,有点 调用 clearFouse()方法...
    99+
    2022-06-06
    edittext 默认 Android
  • win10系统怎么取消自动更新
    这篇文章主要介绍“win10系统怎么取消自动更新”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“win10系统怎么取消自动更新”文章能帮助大家解决问题。操作方法:在“搜索web和windows”框中,...
    99+
    2023-06-28
  • 怎么取消电脑的自动关机
    要取消电脑的自动关机,你可以按照以下步骤进行操作:1. 打开"控制面板",可以通过在Windows搜索栏中输入"控制面板"来找到它。...
    99+
    2023-08-29
    电脑
  • win10声卡驱动怎么取消自动安装
    这篇文章主要介绍了win10声卡驱动怎么取消自动安装的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇win10声卡驱动怎么取消自动安装文章都会有所收获,下面我们一起来看看吧。 ...
    99+
    2023-01-30
    win10
  • wps ppt自动播放取消怎么设置
    本篇内容介绍了“wps ppt自动播放取消怎么设置”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!如果正在播放ppt,可以先右键画面,将它“结...
    99+
    2023-07-02
  • steam下载完怎么自动关机取消
    这篇“steam下载完怎么自动关机取消”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“steam下载完怎么自动关机取消”文章吧...
    99+
    2023-07-02
  • 亚马逊云自动扣款怎么取消
    1、登录AWS控制台,点击右上角的用户名(你的账户),在下拉菜单中选择我的账户控制面板(billing dashboard); 2、点击Bill Details,会进入详细信息页面,此处会显示您的账单信息,包括日期、消费金额、付款方式等。...
    99+
    2023-10-27
    亚马逊
  • 如何取消Win7启动自动运行程序
    每天,公司首先打开电脑。很多用户发现打开电脑很慢。取消启动自动运行程序其实很简单,可能是因为启动的程序太多了。如若不了解如何取消Win7启动时自动运行程序,建议迅速浏览小系列的教程。一、开机自动启动软件困扰大家吗?从下图可以看出,电脑一开机...
    99+
    2023-07-24
  • 怎么让windows8系统自动关机及取消自动关机
    打开电脑进入Win8系统桌面,按Win+X快捷键在弹出菜单中点击“运行”(或Win+R打开运行),比如,我们想让电脑在三个小时后自动关机,在打开运行框中输入“shutdo...
    99+
    2022-06-04
    自动关机 系统
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作