【问题标题】:Update viewmodel from a different class从不同的类更新视图模型
【发布时间】:2019-03-25 00:10:30
【问题描述】:

我正在尝试了解 ViewModel 和 LiveData。

在 MainActivity 中,我正在观察 LiveData 在 MyTask 中,我在 LiveData 上设置数据,这些数据应该显示在活动中。

问题是 MyTask 中的数据集没有在 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 类

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 类

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");

    }
}

【问题讨论】:

  • 不要在你的任务中创建MyViewModel的新实例,传入你在Activity中获得的那个
  • @EpicPandaForce 有没有一种方法可以在不通过的情况下在任务中创建实例?我知道拥有单例 ViewModel 类不是一个好主意
  • 随便new MyTask(viewModel)
  • 是的,我正在尝试探索其他方式,我不想通过任何活动参考。
  • 您没有传递 Activity 引用,而是传递了 ViewModel 引用。 ??????

标签: android android-livedata android-viewmodel


【解决方案1】:

而不是创建一个新实例,只需传递视图模型的创建实例

public MyTask(MyViewModel myViewModel)  { 
   viewmodel = myViewModel;
}

然后尝试更新Ui

要更新观察者,视图模型需要活动上下文..在其中观察实时数据..您正在 AsyncTask 内创建视图模型的单独实例..

【讨论】:

  • 它已经在 MainActivity 中了。我正在使用 viewModel = ViewModelProviders.of(this).get(MyViewModel.class); 创建在 MyTask 中,我使用的是 new 关键字。
  • 您正在使用应用程序上下文...这不是正确的方式...在承包商中您应该传递活动上下文...
  • 我想使用使用该应用程序的 AndroidViewModel。要在 LiveModel 中设置数据,为什么需要活动?
  • 即使我创建 viewModel = new MyViewModel(getApplication());在 MainActivity 和 MyTask 中,它不起作用,因为它们都使用不同的 ViewModel 实例?
  • 你从哪里开始 AsyncTask ?
【解决方案2】:

根据https://medium.com/androiddevelopers/viewmodels-and-livedata-patterns-antipatterns-21efaef74a54

“而不是试图通过库或扩展来解决这个问题 架构组件,它应该作为一个设计问题来面对。我们 建议您将您的活动视为您所在州的一部分。”

我们不应该共享 livedata 或 viewmodel 实例。

Activity -> Viewmodel -> Repository

Activity 应该包含 viewModel 的实例。如果单击按钮,则应通知应启动任务的视图模型。在 viewmodel 中得到响应后,更新 livedata。它会自动在 Activity 中得到通知。

【讨论】:

  • 如果我们想将 ViewModel 传递给另一个类,并从该类而不是初始化它的那个类中调用 ViewModel 上的更新和插入函数怎么办?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-09
  • 2013-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多