Android Jetpack架構之LiveData
阿新 • • 發佈:2021-08-28
一、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) } }