• Android Jetpack之ViewModel、LiveData


    Android Jetpack之LifeCycle

    目录

    前言

    一、ViewModel

    1、解决的问题:

    2、注意点事项:

    3、ViewModel案例:

    二、LiveData

    1、viewmodel+ livedata使用案例

    2、viewmodel+ livedata 优势总结


    前言

            Jetpack是一个由多个技术库组成的套件,可帮助开发者遵循最佳做法,减少样板代码并编写可在各种Android版本和设备中一致运行的代码,让开发者精力集中编写重要的代码。

    一、ViewModel

            ViewModel是介于View(视图)和Model(数据模型)之间的中间层,能够使视图和数据分离,又能提供视图和数据之间的通信。如图所示:

     

    1、解决的问题:

    • 屏幕翻转后页面数据的丢失;
    • 异步调用导致的内存泄露;
    • 类膨胀提高维护难度和测试难度;

    2、注意点事项:

    • ViewModel的生命周期要比Activity的生命周期更长,因此在使用ViewModel时,不要向ViewModel传入Activity的Context,因为这样会导致内存泄露。
    • 如果必须使用Context,可使用AndroidViewModel中的Application。

    3、ViewModel案例:

            我们知道,Android横竖屏切换时,当前的Activity会被销毁重建,然后Activity上面的数据将会全部丢失。(如Listview上面每个item的checkbox,横竖屏切换时,复选框就丢失所有选中信息)。一般,我们解决办法是,在配置清单Androidmanifest.xml的activity标签中加入android:configChanges="orientation|keyboardHidden",或在Activity里面通过复写onConfigurationChanged方法,实现在不同的屏幕状态下的处理方式。

            那么,使用ViewModel将会是怎样的?

            首先,创建一个连接层类MyViewModel.kt  继承 AndroidViewModel,里面定义了number变量。

    1. class MyViewModel(application: Application) : AndroidViewModel(application) {
    2.     var number = 0 //
    3. }

    然后,在activity中使用:

    1. class TestActivity : AppCompatActivity() {
    2.     private var textView: TextView? = null
    3.     private var viewModel: MyViewModel? = null
    4.     override fun onCreate(savedInstanceState: Bundle?) {
    5.         super.onCreate(savedInstanceState)
    6.         setContentView(R.layout.activity_main)
    7.         textView = findViewById(R.id.textView)
    8.         //实例化viewModel
    9.         viewModel =ViewModelProvider(this,
    10. AndroidViewModelFactory(application))[MyViewModel::class.java]
    11.         //显示数据
    12.         textView!!.text = String.valueOf(viewModel!!.number)
    13.     }
    14. //点击事件
    15.     fun plusNumber(view: View) {
    16.         textView!!.text = String.valueOf(++viewModel!!.number)
    17.     }
    18. }

            实例化对应的viewModel后,通过访问viewModel里的属性number,不管怎么切换横竖屏,对应的屏幕上的数字都不会被清空。


    二、LiveData

            如上案例中,如果点击事件只是改变了viewmodel中的number值,text就不会刷新显示。LiveData就是一个能够在ViewModel中数据发生变化时通知页面刷新UI线程的组件库。LiveData和ViewModel的关系,如下图所示:

     

    1、viewmodel+ livedata使用案例

    首先,修改一下MyViewModel.kt

    1. class MyViewModel : ViewModel() {
    2. //定义LiveData集合
    3. private var linkNumber: MutableLiveData<Int>? = null
    4. //得到LiveData集合
    5. fun getLinkNumber(): MutableLiveData<Int>? {
    6. if (linkNumber == null) {
    7. //初始化
    8. linkNumber = MutableLiveData()
    9. linkNumber!!.value = 0
    10. }
    11. return linkNumber
    12. }
    13. //给外部提供修改集合内部属性的方法
    14. fun addLinkedNumber(n: Int) {
    15. linkNumber!!.value = linkNumber!!.value!! + n
    16. }
    17. }

    在activity中使用:

    1. class MainActivity : AppCompatActivity() {
    2. private var viewModel: MyViewModel? = null
    3. override fun onCreate(savedInstanceState: Bundle?) {
    4. super.onCreate(savedInstanceState)
    5. setContentView(R.layout.activity_main)
    6. val textView: TextView = findViewById(R.id.textView)
    7. viewModel =ViewModelProvider(this,
    8. AndroidViewModelFactory(application))[MyViewModel::class.java]
    9. //观察
    10. viewModel!!.getLinkNumber()!!.observe(this, Observer {
    11. textView.text = String.valueOf(it)
    12. })
    13. }
    14. fun reduce(view: View) {
    15. viewModel!!.addLinkedNumber(-1)
    16. }
    17. fun add(view: View) {
    18. viewModel!!.addLinkedNumber(1)
    19. }
    20. }

            上面案例中,ViewModel的初始化不变。在点击事件中调用addLinkedNumber()方法,对ViewModel对应LiveData集合进行修改操作。viewModel!!.getLinkNumber()!!.observe(this, Observer {xx},来接受ViewModel发过来的修改通知,并及时更新至textView上。

    2、viewmodel+ livedata 优势总结

    • 页面翻转数据状态保留
    • 不再需要手动处理生命周期
    • 数据始终保持最新状态
    • 不会发生内存泄露
    • 异步情况,不会因Activity停止而导致崩溃

  • 相关阅读:
    【python脚本】ICer的脚本入门训练——gen_tc
    Promise 重写 (第一部分)
    实现el-upload可以选择文件夹
    修改Office2021 默认安装路径
    【MAPBOX基础功能】22、mapbox根据指定中心点绘制指定公里数的矩形
    精品基于Python房源爬虫实现数据可视化分析
    开源组件漏洞检测工具之 ide 插件 by 大龙
    day02-Gateway(网关)
    基于Docker从零到一实操MySql的主从复制
    数据库优化(8月27号)
  • 原文地址:https://blog.csdn.net/csdn_aiyang/article/details/126828596