zoukankan      html  css  js  c++  java
  • Android LiveData使用

    LiveData是一个可观察的数据持有者类。 与常规observable不同,LiveData是生命周期感知的,当生命周期处于STARTED或RESUMED状态,则LiveData会将其视为活动状态,这意味着它尊重其他应用程序组件的生命周期,例如Activity,Fragment或Service。
    LiveData具有以下优点:

    • UI和数据保持一致:遵循观察者模式,生命周期状态更改时,LiveData会通知Observer对象
    • 避免内存泄漏:观察者绑定到Lifecycle对象,并在其相关生命周期被破坏后自行清理
    • 不会因stop而崩溃:处于非活动状态,不会接收到LiveData事件,如Activity变为不可见
    • 自动感知生命周期:LiveData自动管理在观察时意识到相关的生命周期状态变化。
    • 数据始终保持最新:生命周期变为非活动状态再次变为活动状态时接收最新数据。 例如,Activity不可见变为可见时立即接收最新数据
    • 解决Configuration changes问题:当屏幕旋转或者回收时,重新创建Activity或Fragment,可以即时收到数据变更
    • 共享资源:使用单例扩展LiveData,就可在app中共享它
    • gradle配置
    def lifecycle_version = "2.0.0"
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version" 
    
    • 创建LiveData对象
    class TestViewModel : ViewModel() {
        private lateinit var userName: MutableLiveData<String>
    
        fun getUserName(): MutableLiveData<String> {
            if (!::userName.isInitialized) {
                userName = MutableLiveData()
                loadUsers()
            }
            return userName
        }
    
        private fun loadUsers() {
            userName.value = "test"
        }
    }
    
    • 观察和变更LiveData对象
    class MainActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            var model = ViewModelProviders.of(this).get(TestViewModel::class.java)
            model.getUserName().observe(this, Observer {
                txt_test.text = it
            })// 观察
            btn_test.setOnClickListener {
                model.getUserName().value = "test 2"
            }// 变更
        }
    }
    

    在变更数据的使用有两种方式可用,一个是setValue,另外一个是postValue,区别是setValue只能在主线程处理,postValue可以在子线程处理。

    • LiveData结合Databinding使用
    class MainActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            var binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
            var model = ViewModelProviders.of(this).get(TestViewModel::class.java)
            binding.let {
                it.data = model
                it.setLifecycleOwner(this)
            }
            btn_test.setOnClickListener {
                model.getUserName().value = "test 2"
            }
        }
    }
    

    binding对象需要调用setLifecycleOwner(LifecycleOwner lifecycleOwner)设置lifecycleOwner对象。

    • 扩展LiveData

    通常LiveData只关心观察者的STARTED或RESUMED状态,下面代码片段扩展了LiveData

    class StockLiveData(symbol: String) : LiveData<BigDecimal>() {
        private var mStockManager: StockManager? = null
    
        private val mListener = object : SimplePriceListener() {
            fun onPriceChanged(price: BigDecimal) {
                value = price
            }
        }
    
        init {
            mStockManager = StockManager(symbol)
        }
    
        override fun onActive() {
            mStockManager.requestPriceUpdates(mListener)
        }
    
        override fun onInactive() {
            mStockManager.removeUpdates(mListener)
        }
    }
    

    实现包括以下重要方法:

    • 当 LiveData 对象具有活跃观察者时,会调用 onActive() 方法。这意味着,您需要从此方法开始观察数据更新。
    • 当 LiveData 对象没有任何活跃观察者时,会调用 onInactive() 方法。由于没有观察者在监听,因此没有理由与 StockManager 服务保持连接。
    • setValue(T) 方法将更新 LiveData 实例的值,并将更改通知给任何活跃观察者。
    • 使用扩展LiveData
    class TestFragment : Fragment() {
    
        override fun onActivityCreated(savedInstanceState: Bundle?) {
            super.onActivityCreated(savedInstanceState)
            val stockLiveData = StockLiveData("")
            stockLiveData.observe(this, Observer {
                // update UI
            })
        }
    }
    

    observe() 方法将传递 Fragment(它是 LifecycleOwner 的实例)作为第一个参数。这样做表示此观察者绑定到与所有者关联的 Lifecycle 对象,这意味着:

    • 如果 Lifecycle 对象未处于活跃状态,那么即使值发生更改,也不会调用观察者。
    • 销毁 Lifecycle 对象后,会自动移除观察者

    当然可以在多个 Activity、Fragment 和 Service 之间共享它们,只需要把 StockLiveData类实现为单例。

    • 转换 LiveData

    LiveData 对象分派给观察者之前对存储在其中的值进行更改,或者您可能需要根据另一个实例的值返回不同的 LiveData 实例。其提供了以下方法进行转换

    • Transformations.map()
    LiveData<User> userLiveData = ...;
    LiveData<String> userName = Transformations.map(userLiveData, user -> {
        user.name + " " + user.lastName
    });
    
    • Transformations.switchMap()
    LiveData<String> userId = ...;
    LiveData<User> user = Transformations.switchMap(userId, id -> getUser(id) );
    

    要实现您自己的转换,可以使用 MediatorLiveData 类,该类可以监听其他 LiveData 对象并处理它们发出的事件,其可以正确地将其状态传播到源 LiveData 对象。

  • 相关阅读:
    P1182 数列分段`Section II` 二分
    洛谷 P1025 数的划分
    深浅拷贝
    数据的内置方法
    控制流程-if/while/for
    python的基本运算符
    花式赋值
    python的注释
    Python的垃圾回收机制
    变量与常量
  • 原文地址:https://www.cnblogs.com/fomin/p/10490816.html
Copyright © 2011-2022 走看看