Android MutableLiveData and AndroidViewModel pit avoidance tips, Java
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import android.app.Application;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
private String TAG = "fly";
private MyData myData = new MyData();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyModel myModel = new MyModel(this.getApplication());
myData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
Log.d(TAG, "onChanged - " + s);
}
});
myModel.start();
}
private class MyData extends MutableLiveData<String> {
@Override
public void setValue(String value) {
super.setValue(value);
Log.d(TAG, "setValue - " + value);
}
@Override
public void postValue(String value) {
super.postValue(value);
Log.d(TAG, "postValue - " + value);
}
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super String> observer) {
super.observe(owner, observer);
Log.d(TAG, "observe");
}
@Override
protected void onActive() {
super.onActive();
Log.d(TAG, "onActive");
}
@Override
protected void onInactive() {
super.onInactive();
Log.d(TAG, "onInactive");
}
}
public class MyModel extends AndroidViewModel {
public MyModel(@NonNull Application application) {
super(application);
}
public void start() {
for (int i = 0; i < 3; i++) {
myData.postValue("a " + i);
SystemClock.sleep(100);
}
SystemClock.sleep(1000);
for (int i = 5; i < 8; i++) {
myData.setValue("b " + i);
SystemClock.sleep(100);
}
}
}
}
output:
(1) setValue() must be called on the UI main thread. And postValue() can be called on a background thread (non-UI thread).
(2) setValue() is after postValue().
(3) Before the LiveData setting (UI thread) data task, if postValue() multiple data, but only the last data will be distributed to the main thread setting. It can be simply understood that the final data presentation of postValue() is the implementation of setValue().
(4) After potsValue(), getValue() may not necessarily get the data in postValue(), only after the main thread setValue(), can get the value of postValue(). In other words, unless the main thread setsValue() the value of postValue(), it cannot be fetched.