问题
I am trying to understand ViewModel and LiveData.
In MainActivity, I am observing LiveData In MyTask, I am setting data on the LiveData, that should be displayed in the activity.
Problem is data set in MyTask is not getting updated on the UI.
MainActivity
public class MainActivity extends AppCompatActivity {
private MyViewModel viewModel;
private TextView tv2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv2 = findViewById(R.id.textView2);
viewModel = ViewModelProviders.of(this).get(MyViewModel.class);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
viewModel.setNameData("Button clicked");
new MyTask(getApplication()).execute();
}
});
viewModel.getNameData().observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
tv2.setText(s);
}
});
}
}
ViewModel class
public class MyViewModel extends AndroidViewModel {
private MutableLiveData<String> nameData = new MutableLiveData<>();
public MutableLiveData<String> getNameData() {
return nameData;
}
public void setNameData(String name) {
nameData.postValue(name);
}
public MyViewModel(@NonNull Application application) {
super(application);
}
}
MyTask class
public class MyTask extends AsyncTask<Void, Void, Void> {
private MyViewModel viewModel;
public MyTask(Application application){
viewModel = new MyViewModel(application);
}
@Override
protected Void doInBackground(Void... voids) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
viewModel.setNameData("Done task");
}
}
回答1:
Instead of creating a new instance just pass the created instance of viewmodel
public MyTask(MyViewModel myViewModel) {
viewmodel = myViewModel;
}
And then try to update the Ui
To update the observer the viewmodel needs the activity context ..inside which the livedata is observed.. you are creating a separate instance of the viewmodel inside the AsyncTask..
回答2:
According to https://medium.com/androiddevelopers/viewmodels-and-livedata-patterns-antipatterns-21efaef74a54
"Instead of trying to solve this with libraries or extensions to the Architecture Components, it should be faced as a design problem. We recommend you treat your events as part of your state."
We should not share the livedata or viewmodel instance.
Activity -> Viewmodel -> Repository
Activity should contain instance of a viewModel. If the button is clicked, it should be notified to the viewModel which shall start the task. After getting response in viewmodel, update the livedata. It will automatically get notified in the Activity.
来源:https://stackoverflow.com/questions/55329800/update-viewmodel-from-a-different-class