1、LiveData到底是個啥?
LiveData是可以在給定生命週期內觀察到的數據持有者類。
它是一個類,這個類可以幹嘛呢?
可以在給定的生命週期內觀察數據變化。
給定的生命週期是什麼意思?
指的是AppCompatActivity的onStart() 和 onResume()方法。
爲什麼要是AppCompatActivity 這個類而不是單純的Activity類呢?
很簡單當我們查看AppCompatActivity類的源碼時發現它實現了LifecycleOwner 這個接口。
LifecycleOwner 這個接口有什麼用?
爲了實現數據變化的感知,需要實現觀察者模式。
所以單靠區區一個類LiveData類還不能實現觀察者模式,需要結合LifecycleOwner 接口實現類。爲啥我們不需要直接去實現它,因爲AppCompatActivity 的這個【ComponentActivity】父類已經實現了LifecycleOwner 這個接口,所以我們可以直接使用LiveData進行數據變更,就會有對應的生命週期響應。
接下來我們看看應該怎麼樣在實際案例中使用它。
使用之前我們需要在app的build.gradle文件中配置:
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
2、具體案例
佈局activity_live_data.xml:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="dataBean"
type="com.hb.mvvm.livedata.DataBeanViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@={dataBean.data}" />
</LinearLayout>
</layout>
實體類DataBeanViewModel.class:
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
/**
* Created by Administrator
* on 2020/3/31
*/
public class DataBeanViewModel extends ViewModel {
//<String> 可以換成對應的實體類型 eg:<User>
MutableLiveData<String> dbLiveData = new MutableLiveData<>();
//獲取LiveData對象實例
public MutableLiveData<String> getData() {
return dbLiveData;
}
}
類LiveDataActivity.class :
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.ViewModelProvider;
import com.hb.mvvm.R;
import com.hb.mvvm.databinding.ActivityLiveDataBinding;
import org.w3c.dom.Text;
public class LiveDataActivity extends AppCompatActivity {
ActivityLiveDataBinding liveDataBinding;
final String TAG = LiveDataActivity.class.getSimpleName();
DataBeanViewModel dbViewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
liveDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_live_data);
//設置觀察
liveDataBinding.setLifecycleOwner(this);
//創建DataBeanViewModel 的實例
dbViewModel = new ViewModelProvider(this).get(DataBeanViewModel.class);
//使用實例
liveDataBinding.setDataBean(dbViewModel);
liveDataBinding.tv.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
Log.i(TAG, "觀察TextView數據變化: " + s);
}
});
}
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "onStart()");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume()");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause()");
//爲了查看數據是否能夠恢復,切換到後臺的時候將數據置空
liveDataBinding.tv.setText("");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "onStop()");
//停止的時候設置數據,看看在OnResume之後能否在顯示出數據
dbViewModel.getData().postValue("ViewModel配合LiveData使用");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy()");
}
}
輸出:
onStart()
onResume()
onPause()
觀察TextView數據變化:
onStop()
onStart()
onResume()
觀察TextView數據變化: ViewModel配合LiveData使用
onPause()
觀察TextView數據變化:
onStop()
onStart()
onResume()
觀察TextView數據變化: ViewModel配合LiveData使用
onPause()
觀察TextView數據變化:
onStop()
onStart()
onResume()
觀察TextView數據變化: ViewModel配合LiveData使用
onPause()
觀察TextView數據變化:
onStop()
onDestroy()
onStart()
onResume()
onPause()
觀察TextView數據變化:
onStop()
onDestroy()
輸出中可以看到TextView數據恢復時都是在onResume()之後,但是onStart() 貌似沒有體現出來。
當我們沒調用onDestroy()方法時,每次切換顯示界面都會恢復之前設置的數據,否則數據將會不在恢復。
這個過程保證了數據能完整的伴隨生命週期的過程,相對而言數據恢復這塊比之前的方式savedInstanceState更加方便。
同時通過查閱資料,當生命週期處於onDestory時,觀察者會自動刪除,防止內存溢出。
3、總結
LiveData 會自己管理自己的生命週期,防止內存溢出。
LiveData 能更好的幫助我們數據恢復,貫穿到整個Activity生命週期。
案例中發現當在onResume的時候看到纔會恢復數據。而onStart()的時候沒有做具體的實驗,希望留給後面進行嘗試。