Update viewmodel from a different class

北慕城南 提交于 2019-12-10 11:57:25

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!