Android Jetpack架构之LiveData

一、LiveData是什么?

  LiveData是可观察数据存储器类,与常规可观察数据存储类不同,LiveData具有对系统组件(如:Activity、Fragment、Service等)的生命周期感知能力。

  LiveData只有在生命周期的活跃状态下才会更新数据,即start、resume,非活跃状态pause、stop是不会更新数据的。如下所示:

  LiveData只有在活跃状态下才会通知更新数据,也就是start和resume生命周期状态下,当组件进入onPause或者onStop生命周期状态下,当前组件非活跃状态下不会通知更新数据,在非活跃状态下有ViewModel有数据更新,在组件状态从onPause或者onStop非活跃状态进入活跃状态onStart或者onResume下,会通知组件数据更新。

1 D/Test: start
2 D/Test: resume
3 D/Test: update data: 1
4 D/Test: pause
5 D/Test: stop
6 D/Test: changed value print // Model更新数据但未通知组件更新数据
7 D/Test: start
8 D/Test: update data: 10 // 组件进入活跃状态下更新数据
9 D/Test: resume

 

二、LiveData的优点

  • 不需要手动控制生命周期。
  • 不会因为Activity的停止,导致App崩溃。
  • 数据状态始终保持最新。
  • 不会产生内存泄漏。

三、LiveData Api

/**
 * {@link LiveData} which publicly exposes {@link #setValue(T)} and {@link #postValue(T)} method.
 *
 * @param <T> The type of data hold by this instance
 */
@SuppressWarnings("WeakerAccess")
public class MutableLiveData<T> extends LiveData<T> {

    /**
     * Creates a MutableLiveData initialized with the given {@code value}.
     *
     * @param value initial value
     */
    public MutableLiveData(T value) {
        super(value);
    }

    /**
     * Creates a MutableLiveData with no value assigned to it.
     */
    public MutableLiveData() {
        super();
    }

    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}
  • 非UI线程使用postValue()方法。
  • UI线程使用setValue()方法。

四、示例

  RViewModel类:

class RViewModel : ViewModel() {

    val count: MutableLiveData<Int> = MutableLiveData()

}

  MainActivity类:

class MainActivity : AppCompatActivity() {

    private var _rViewModel: RViewModel? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        _rViewModel = ViewModelProvider(this).get(RViewModel::class.java)

        _rViewModel?.count?.observe(this, {
            countText.text = "$it"
        })

        startTimer()
    }

    private fun startTimer() {
        Timer().schedule(object : TimerTask() {

            override fun run() {
                val count = (_rViewModel?.count?.value ?: 0) + 1
                // UI线程使用setValue()
                // 非UI线程使用postValue()
                // timer task是子线程,所以使用postValue()
                _rViewModel?.count?.postValue(count)
            }

        }, 1000, 1000)
    }

}

 

上一篇:Jetpack Compose之隐藏Scaffold的BottomNavigation


下一篇:Jetpack Compose---> Navigation组件的基本使用