1. 程式人生 > 其它 >Android Jetpack架構之LiveData

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)
    }

}