ViewModel和LiveData的基本使用

这篇具有很好参考价值的文章主要介绍了ViewModel和LiveData的基本使用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


ViewModel和LiveData的基本使用

ViewModel是干什么的?

在页面(活动/碎片)中,在很简单的情况在我们会将UI交互,数据的获得与处理等相关的逻辑,全都放在一个页面中,但是如果我们要处理的业务很复杂,这样做会显得代码冗杂且不利于解读,这样不符合"单一责任"原则.
所以页面就应该只是负责接收用户的交互以及数据的展示,其他逻辑应该放在另外一个东西上面,为此,Android为我们提供了ViewModel类,专门用来存放应用程序页面所需要的数据.它将页面中所需要的数据从页面中剥离出来.
ViewModel和LiveData的基本使用
另外,如果我们的应用程序支持横竖屏切换,当用户旋转手机屏幕时,我们还需要考虑数据的存储与恢复。如果数据不进行存储,那么通常我们还需要重新去获取一次。

而ViewModel能为我们解决这个问题,它独立于配置变化。也就是说,屏幕旋转导致的Activity重建,并不会影响到ViewModel的生命周期
ViewModel和LiveData的基本使用

LiveData是干什么的?

  1. 首先LiveData是一种可观察监听的数据存储类,当生命周期发生,数据有更新时,observer可感知监听到.

  2. 其次LiveData其实也是一个观察者模式的数据实体类,它可以跟它注册的观察者回调数据是否已经更新.

  3. LiveData还能知晓它绑定的Activity或者Fragment的生命周期,它只会给前台活动的activity回调(这个很厉害).这样你可以放心的在它的回调方法里直接将数据添加到View,而不用担心会不会报错.(你也可以不用费心费力判断Fragment是否还存活)

LiveData和ViewModel实现跨页面通信

官方建议LiveData和ViewModel一起使用,因为 ViewModel 支持共享作用域,并且官方文档都推荐了通过 共享 ViewModel 来实现跨页面通信的需求:
ViewModel和LiveData的基本使用
在这里我们使用LiveData和ViewModel实现一个小demo,ViewModel里面创建一个Timer计时器,每隔一秒,通过LiveData来更新主界面的UI,这种方法在只用之后我们可以清楚的看到,如果手机从横屏切换到竖屏,或者竖屏切换到横屏,它ViewModel里面Timer计时器,都不会重新开始计时.

1. 首先创建一个TimerViewModel类继承ViewModel

LiveData是一个数据的包装。具体的包装对象可以是任何数据,包括集合。它是一个抽象类,首先先创建一个类实现LiveData

public class TimerViewModel extends ViewModel
{
    private Timer timer;
    private int currentSecond;

    /**
     * LiveData是抽象类,MutableLiveData是具体实现类
     */
    private MutableLiveData<String> content;

    public MutableLiveData<String> getContent(){
        if(content == null){
            content = new MutableLiveData<>();
        }
        return content;
    }
    
    /**
     * 开始计时
     * */
    public void startTiming()
    {
        if (timer == null)
        {
            currentSecond = 0;
            timer = new Timer();
            TimerTask timerTask = new TimerTask()
            {
                @Override
                public void run()
                {
                    currentSecond++;
                    content.postValue(String.valueOf(currentSecond));
                }
            };
            timer.schedule(timerTask, 2000, 1000);//延迟2秒执行
        }
    }
    
    /**
     * 由于屏幕旋转导致的Activity重建,该方法不会被调用
     *
     * 只有ViewModel已经没有任何Activity与之有关联,系统则会调用该方法,你可以在此清理资源
     * */
    @Override
    protected void onCleared()
    {
        super.onCleared();
        timer.cancel();
    }
}

ViewModel是一个抽象类,其中只有一个方法onCleared(),当ViewModel不再被需要的时候,也就是与之相关的Activity都被销毁时,该方法会被系统调用,我们可以在这个方法里面执行一些资源释放的操作,以免内存泄漏。

既然ViewModel的销毁是由系统来判断和执行的,那么系统是如何判断的呢?是根据Context引用。因此,我们在使用ViewModel的时候,千万不能从外面传入Activity,Fragment或者View之类的含有Context引用的东西,否则系统会认为该ViewModel还在使用中,从而无法被系统销毁回收,导致内存泄漏的发生。

2. 在Activity或是fragment进行监听观察

public class MainActivity extends AppCompatActivity
{

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iniComponent();
    }

    private void iniComponent()
    {
        TextView tvTime = findViewById(R.id.tvTime);
        //构建了ViewModel对象
        TimerViewModel timerViewModel = new ViewModelProvider(this).get(TimerViewModel.class);

		//监听了content属性变化,只要触发了setValue/postValue方法就会走
        timerViewModel.getContent().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                tvTime.setText("TIME: " + s);
            }
        });
        timerViewModel.startTiming();
    }
}

首先创建一个 MutableLiveData(LiveData是抽象类)对象 ,通过 observe 方法可以订阅修改数据的通知,通过 postValue()或者 setValue() 方法发送事件更新数据,已经订阅的 Observer 能够得到数据更改的通知,就会回调 onChanged() 方法。

// 在UI线程中调用该方法通知数据变更
liveData.setValue(object);

// 在子线程中调用该方法通知数据变更,该方法中切换到UI线程后调用setValue方法
liveData.postValue(object);

总结

我们前面提到过,使用ViewModel的时候,不能将任何含有Context引用的对象传入ViewModel,因为这可能会导致内存泄露。但如果你希望在ViewModel中使用Context怎么办呢?我们可以使用AndroidViewModel类,它继承自ViewModel,并且接收Application作为Context,既然是Application作为Context,也就意味着,我们能够明确它的生命周期和Application是一样的,这就不算是一个内存泄露了。

使用ViewModel,不仅将界面和数据从代码上进行了分离,而且不再需要关心屏幕旋转带来的数据的丢失和获取问题。也许你会说onSaveInstanceState() 方法同样可以解决屏幕旋转带来的数据丢失问题,但它只能保存少量的能支持序列化的数据,而ViewModel没有这个限制,它能支持页面中所有的数据。但要注意的是,ViewModel不支持数据的持久化,当界面彻底销毁,ViewModel及其数据也就不存在了。文章来源地址https://www.toymoban.com/news/detail-461209.html

到了这里,关于ViewModel和LiveData的基本使用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 大数据是干什么的?

    大数据技术的战略意义不在于掌握庞大的数据信息,而在于对这些有意义的数据进行专业的处理。换句话说,如果把大数据比作一个行业,这个行业盈利的关键在于提高数据的“处理能力”,通过“处理”实现数据的“增值”。 从技术上讲,大数据和云计算的关系就像硬币的

    2024年01月21日
    浏览(39)
  • 服务器是什么?它是用来干什么的?

    作者: Insist-- 个人主页: insist--个人主页 作者会持续更新网络知识和python基础知识,期待你的关注   目录 一、服务器是什么? 二、服务器的作用 1、提高访问速度 2、提高安全性 三、云服务器与物理服务器 1、云服务器 云服务器的优点: 2、物理服务器 物理服务器的优点:

    2024年02月08日
    浏览(55)
  • 什么是tomcat?tomcat是干什么用的?

    什么是tomcat Tomcat是常见的免费的web服务器. Tomcat 这个名字的来历,Tomcat是一种野外的猫科动物,不依赖人类,独立生活。 Tomcat的作者,取这个名字的初衷是希望,这一款服务器可以自力更生,自给自足,像Tomcat这样一种野生动物一般,不依赖其他插件,而可以独立达到提供

    2023年04月11日
    浏览(46)
  • python cv2是什么,可以用来干什么

    OpenCV (Open Source Computer Vision Library) 是一个流行的开源计算机视觉库,提供了丰富的图像和视频处理功能。通过使用 OpenCV 的 Python 绑定库 cv2,可以实现以下一些功能: 图像读取和显示:使用 cv2.imread() 读取图像文件,使用 cv2.imshow() 显示图像窗口。 图像处理:包括图像滤波、

    2024年02月14日
    浏览(42)
  • Hessian 矩阵汉语叫什么名字,是什么意思,是用来干什么的?

    问题描述:Hessian 矩阵汉语叫什么名字,是什么意思,是用来干什么的? 问题解答: Hessian 矩阵的汉语名字是“黑塞矩阵”或“海森矩阵”。 这个名字的来源是对德国数学家Ludwig Hessian(海森)的姓氏的翻译。Hessian 矩阵是一个方阵,其中的元素是一个函数的二阶偏导数,用

    2024年01月22日
    浏览(51)
  • node.js是干什么的

    Node.js是一个开源和跨平台的JavaScript运行时环境。它几乎是任何类型项目的流行工具! Node.js在浏览器之外运行V8 JavaScript引擎(Google Chrome的内核)。这使得Node.js的性能非常好。 Node.js应用程序在单个程序中运行,无需为每个请求创建新的线程。Node.js在其标准库中提供了一组异

    2023年04月09日
    浏览(39)
  • 在线ios免签是干什么的?

    在本教程中,我们将介绍在iOS设备上实现免签名应用程序安装的原理和详细步骤。首先,请注意,这些应用程序通常可能存在风险,因为它们没有经过苹果官方的签名审核。但是,现实中确实有一些情况,您可能需要安装一些非官方渠道的iOS应用。在这种情况下,下面的内容

    2024年02月07日
    浏览(42)
  • SpringBoot 配置文件:什么是配置文件?配置文件是干什么?

    学习一个东西,我们先要知道它有什么用处。整个项目中所有重要的数据都在配置文件中配置,例如:数据库的连接信息、项目启动窗口、第三方系统调用密钥、日志等级…,如果没有配置信息,那么 SpringBoot 项目就无法连接数据库,不能保存关键日志,因此,在项目中,配

    2024年02月16日
    浏览(42)
  • DNS劫持是什么意思?DNS劫持是干什么用的?

    DNS劫持又称域名劫持,是指在劫持的网络范围内拦截域名解析的请求,分析请求的域名,把审查范围以外的请求放行,否则返回假的IP地址或者什么都不做使请求失去响应,其效果就是对特定的网络不能反应或访问的是假网址。 DNS劫持原理 我们以用户访问淘宝网:www.taobao.

    2024年02月08日
    浏览(40)
  • 路由器是什么东西?路由器是干什么用的?

    路由器是什么东西?虽然这个问题对于大多数人来说都不是一个问题,但是任然有少数缺乏网络基础的朋友,不知道路由器到底是个什么东西,本文就简单的介绍一下。 路由器(Router),是连接局域网与局域网、局域网与广域网(Internet)的一种设备,它会根据信道的情况自

    2024年02月08日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包