databinding原理面试(底层原理剖析系列)

前言

在前几年兴起了MVVM架构设计模式,最具有代表的框架就是DataBinding,虽然这种设计架构非常新颖,但是在使用中仍然还有很多痛点,所以我当时觉得短时间这个设计架构可能不会太流行。

最近接手了新项目,使用的就是MVVM,才发现只一两年的功夫MVVM的发展竟然这么快,已经是Android开发者必备的技能之一了。

正文

DataBinding在刚开始阶段,最令我头疼的就是数据处理的问题,往往为了显示数据,我要在XML中绑定N多个字段,如果是一个中等以上的工程,还有更蛋疼的问题,例如:

  • 你的XML可能迫切的需要if或者switch这样的判断;
  • 意想不到的空指针

在2018年,Google推出JetPack库,其中的ViewModel+LIveData终于把MVVM推上了新的高度。

ViewModel

使用ViewModel需要依赖lifecycle库:

implementation "android.arch.lifecycle:viewmodel:x.x.x"
implementation "android.arch.lifecycle:extensions:x.x.x"

ViewModel的创建方法主要有两种:

// 获取FragmentActivity共享的ViewModel
ViewModelProviders.of(FragmentActivity).get(ViewModel::class.java)

// 获取FragmentActivity共享的ViewModel
ViewModelProviders.of(Fragment).get(ViewModel::class.java)

ViewModel的共享范围主要有两种:一种是FragmentActivity,一种是Fragment,可以根据自己的需要选择共享的范围。如果你想要一个Application级别的ViewModel,目前是不支持的,你可以自定义Application持有一个ViewModel,或者使用单例模式。

ViewModel解决的问题

1、扩大数据共享的应用场景。

一般的数据共享是Activity与Fragment的数据传递,传统做法是使用setArguments(Bundle),这种方法有以下弊端:

  • 可能无法预测setArguments会在Fragment的哪个周期完成,要进行异常判断;
  • setArguments中的数据可能会发现改变,如果是Activity直接设置Fragment的数据,耦合性很高;
  • 数据较多时,Fragment会有很多的变量,影响可读性和维护性。

使用ViewModel,可以避免以上的尴尬情况,需要什么数据就从ViewModel中取:

  • 新加数据传递,不用修改Activity的setArguments代码,Fragment也不用编写数据接收的方法;
  • 减少数据传递,不必考虑是否要删除暂时无用的代码;
  • 取数据时,请注意数据的有效性,做好判断即可;

除此之外,自定义View也可以得到ViewModel,这样某些功能耦合性非常强的自定义View开发更加便捷。不过需要注意的是View的context的上下文是Activity类型(不会是Fragment)的,所以只能使用Activity级别的数据共享。

2、解决DataBinding的视图显示问题。

如果视图的显示需要很多的数据,那么XML就会变得越来越臃肿,并且迫切需要添加一些简单的判断,例如:

如果A为空就显示B,如果B为空就先是C,如果是C为空…

虽然DataBinding支持三元运算符,能够满足if判断的需要,但是很显然在XML维护逻辑要比Java或者Kotlin要困难的多(无拼写错误提示等)。所以我们非常需要把部分代码从XML分离出来,ViewModel就非常适合担任这个角色。

修改前:

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>

        <variable
                name="A"
                type="String" />

        <variable
                name="B"
                type="String" />

        <variable
                name="C"
                type="String" />

    </data>

     <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:maxLines="4"
                android:ellipsize="middle"
                android:text="A != null ? A : B != null ? B : C" />
    ...

</layout>

修改后:

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>

        <variable
                name="viewModel"
                type="ViewModel" />

    </data>

    <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:maxLines="4"
                android:ellipsize="middle"
                android:text="@{viewModel.getShowContent()}" />
...

</layout>

LiveData

刚才我们已经讨论了ViewModel的用法,但是还有一个问题没有解决,那就是数据更新的问题,解决这个问题的最佳方式就是观察者模式,但是如果没有处理好观察者的注册和解绑很容易出现内存溢出。LiveData就可以完美的解决这个问题。

我们需要添加LiveData的依赖:

implementation "androidx.lifecycle:lifecycle-livedata:2.1.0"

下面是一个简单的示例:

// 名为openDrawer的Boolean类型的LiveData
public final MutableLiveData<Boolean> openDrawer = new MutableLiveData<>();

// 更新openDrawer 
openDrawer.setValue(true)

// 观察openDrawer 的值的变化
openDrawer.observe(this, aBoolean -> {
             Toast.makeText(this, "${aBoolean}", Toast.LENGTH_SHORT).show();
        });

LiveData的子类是MutableLiveData,内部有value属性保存最新的值,订阅LiveData的变化,直接调用LiveData.observe():

public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)owner:注册的周期,会在owner销毁的时候,解绑观察者。observer:观察的值发生变化的回调函数

owner直接使用Activity或者Fragment即可。如果你还不了解Lifecycle的使用,可以查看一下相关的资料。

总结

最后我画了一张架构图,总结了一下最新的MVVM的使用架构:

使用DataBinding还在为数据处理头疼?这篇文章帮你解决问题

Activity:处理UI问题,但是应当尽量避免这样做,尽量统一使用DataBinding。ViewModel:保存页面需要的数据,功能复杂的话可以拆分成多个。DataBinding:处理UI视图,持有ViewModel做数据展示。如果页面功能比较复杂,可以对ViewModel和DataBinding再次细分。

如果大家对MVVM有更棒的理解,欢迎留言共同学习。

版权声明:本文图片和内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送联系客服 举报,一经查实,本站将立刻删除,请注明出处:https://www.4kpp.com/7365.html

(0)
漫空客漫空客
上一篇 2023年4月23日
下一篇 2023年4月23日

相关推荐

  • 长安UNI-V正式开启预售(11.69万元尊贵型最赞)

    2月21日,长安UNI-V正式开启预售,推出4款车型,官方预售价区间为10.89-13.19万元,同时,车辆提供畅享音质包、运动酷玩包、电动飞翼包供用户选择搭配。对于关注这款车型的…

    2023年4月23日
    940
  • 冒险岛空格名(冒险岛空格名字)

    今天小编给各位分享冒险岛空格名(冒险岛空格名字),如果能碰巧解决你现在面临的问题,别忘了关注小站,我们一起开始吧! 找到冒险岛的装备代码。 做装备的代码是!项目设备代码 如果你打字…

    投稿 2023年4月23日
    3140
  • zara英文怎么读(zara怎么读英文语音读)

    今天就和大家分享一下zara的英语发音知识,也给大家讲解一下zara的英语发音。如果你碰巧解决了你现在面临的问题,别忘了关注这个网站,现在就开始! 如何阅读zara Zara在英语…

    投稿 2023年4月23日
    1230
  • 黑客监控他人微信(怎么监控微信)

    黑客监控他人微信(怎么监控微信)WeChatExtension-ForMac是个非常知名的开源项目,该扩展程序或者叫插件可以为 Mac 版微信添加诸多功能。 鉴于微信官方版更迭速度…

    2023年4月22日
    1220
  • 诗经风雅颂划分标准(诗经的内容风雅颂是按什么划分的)

    今天我要和大家分享的是关于《诗经》中诗词的分类标准的知识,同时我也会解释一下《诗经》中诗词的内容是按照什么来分类的。如果你碰巧解决了你现在面临的问题,别忘了关注这个网站,现在就开始…

    投稿 2023年4月23日
    1030
  • 小语种哪个好学

    今天就和大家分享一下关于哪种小语种好学的问题。以下是这个问题的总结。让我们来看看。 哪种小语种好学? 在全球化的今天,学习外语已经成为许多人不可或缺的一部分。然而,许多人面临着选择…

    投稿 2023年4月23日
    910
  • 魔方入门玩法(魔方入门玩法全新视频第三步)

    今天给大家介绍魔方入门游戏以及魔方入门游戏新视频第三步对应的知识点。希望对你有帮助,也别忘了收藏这个站点。 新手怎么玩魔方? 不知道你有没有拆过魔方?学校里有一股热潮。为了向大家证…

    投稿 2023年4月23日
    1100
  • 抗干扰滤波器(抗干扰滤波器的工作原理)

    今天小编给各位分享抗干扰滤波器(抗干扰滤波器的工作原理),如果能碰巧解决你现在面临的问题,别忘了关注小站,我们一起开始吧! 如何安装防5g干扰过滤器? 1.安装过滤器时,应遵守以下…

    投稿 2023年4月23日
    2140
  • 养卡是什么意思(养卡技巧和方法)

    在用卡过程中,难免会有人犯一些小错误,导致临时额度提不上去,或者被银行警告恶意套现等。 怎么养好卡呢?小编今天来教你几招~ 什么叫养卡? 一般的养卡是指多刷卡多消费,并且及时还款,…

    投稿 2023年4月23日
    890

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注