美文网首页
从面试角度看ViewModel

从面试角度看ViewModel

作者: 艾伦宇 | 来源:发表于2021-11-19 11:09 被阅读0次

一、问题

  1. 为什么要用ViewModel,有什么好处
  2. ViewModel如何在配置变化时保留数据
  3. 在界面旋转时,ViewModel中的请求还在执行吗
  4. ViewModel如何做到在页面销毁时,停止协程中的工作

二、解答

问题1、为什么要用ViewModel,有什么好处

  1. 数据状态的维护
    1. 旋转后保证数据还在
    2. 跟随Activity生命周期的作用域,防止内存泄漏
  2. 便于单元测试
    1. 只用于做纯的业务代码
    2. 不持有Activity或View对象
  3. 便于共享
    同一个Activity下的不同Fragment之间共享

问题2、ViewModel如何在配置变化时保留数据

利用的是Activity重建机制中的NonConfigurationInstances来保存
也就是在配置变化时,Activity会被销毁,但是重建时会从旧的Activity中拿到ViewModelStore

问题3、在界面旋转时,ViewModel中的请求还在执行吗

还会在,并不会调用ViewModel的clear方法
因为系统会判断是否因为页面在旋转导致的,如果是则不销毁ViewModel

        getLifecycle().addObserver(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source,
                    @NonNull Lifecycle.Event event) {
                if (event == Lifecycle.Event.ON_DESTROY) {
                    // Clear out the available context
                    mContextAwareHelper.clearAvailableContext();
                    // And clear the ViewModelStore
                    if (!isChangingConfigurations()) {
                        getViewModelStore().clear();
                    }
                }
            }
        });

问题4、ViewModel如何做到在页面销毁时,停止协程中的工作

这是因为ViewModel会去监听Activity/Fragment的生命周期
在onDestory时,且不需要重建的情况下,会去调用ViewModel的clear方法
在这个方法里面会去close掉所有支持Closeable的对象
如 viewModelScope

//viewModelScope
public 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)
        )
    }
internal class CloseableCoroutineScope(context: CoroutineContext) : Closeable, CoroutineScope {
    override val coroutineContext: CoroutineContext = context
    override fun close() {
        coroutineContext.cancel()
    }
}
// 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();
    }
    private static void closeWithRuntimeException(Object obj) {
        if (obj instanceof Closeable) {
            try {
                ((Closeable) obj).close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

三、参考

Android官方架构组件ViewModel:从前世今生到追本溯源

相关文章

  • 从面试角度看ViewModel

    一、问题 为什么要用ViewModel,有什么好处 ViewModel如何在配置变化时保留数据 在界面旋转时,Vi...

  • 从面试官角度看iOSer应该如何面试

    从面试官角度看iOSer应该如何面试从面试官角度看iOSer应该如何面试

  • 从hr角度看电话面试

    电话面试 一、目的 为了提高面试的有效性,增加参加面试人员的质量、到访率等,优化面试环节,电话面试中初步淘汰筛选出...

  • 从销售角度看如何面试

    很多公司有笔试还有面试。简历海选过了,笔试过了,还有面试。应聘的过程是一场关于应聘者与招聘者之间进行的一场关于人力...

  • 关于产品经理自我能力的检验

    文中是从面试者角度来讲面试产品经理的方法及要求,从读者角度来讲正是检验自身市场价值的方法。 一、面试官的看简历和读...

  • 从面试官角度看iOSer应该如何面试

    开章 一天下午轩老板突然钉钉联系我,告诉我我们事业部要招一个iOS,要我准备一些笔试题和面试题。当时我的第一反应是...

  • 换个角度看Java面试

    找工作离不开面试,不管是Java面试还是其他类型工作的面试,本质就是用你的价值换取money。你的薪资取决于你能为...

  • 关于面试的一些经验

    前言 本文是关于面试经验的分享。以前写过从面试者角度出发的看法,这次从面试官的角度看看如何发掘优质的候选人。 正文...

  • 《聘之有道》

    明理篇:面试为什么---正确看待面试 如果把招聘行为比作成一次销售活动的话,从企业的角度,可以看成是买方,也可以看...

  • 《聘之有道》 - 草稿 - 草稿

    明理篇:面试为什么---正确看待面试 如果把招聘行为比作成一次销售活动的话,从企业的角度,可以看成是买方,也可以看...

网友评论

      本文标题:从面试角度看ViewModel

      本文链接:https://www.haomeiwen.com/subject/limstrtx.html