Android MVVM startActivity的最佳实践

Fel*_*iba 31 android mvvm decoupling android-databinding

我正在使用MVVM和DataBinding构建Android应用程序.我在ViewModel中有一个函数来启动一个Activity.是否可以在ViewModel中进行onClick调用?

像这样.

public class MyViewModel {
    public void onClick(View view, long productId) {
        Context context = view.getContext();
        Intent intent = new Intent(context, ProductDetailActivity.class);
        intent.putExtra("productId", productId);
        context.startActivity(intent);
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的XML中:

...
android:onClick="@{(v) -> viewModel.onClick(v, viewModel.product.id)}">
Run Code Online (Sandbox Code Playgroud)

或者将它移动到View并从EventBus或Rx调用它并在我的ViewModel中只有POJO是最佳做法吗?

Kas*_*asi 19

你的问题的答案是你的目标是什么?

如果你想使用MVVM分离关注点,以便你可以对你进行单元测试,Viewmodel那么你应该尝试保留所有需要Context与你分开的东西Viewmodel.它Viewmodel包含应用程序的核心业务逻辑,并且不应具有外部依赖性.

但是我喜欢你要去的地方:)如果决定打开哪个Activity位于View中,那么为它编写JUnit测试是非常困难的.但是,您可以将对象传递给Viewmodel执行startActivity()调用的对象.现在,在单元测试中,您可以简单地模拟此对象并验证是否Activity已打开正确的对象


Rav*_*avi 9

把它放在里面是绝对完美的ViewModel,但是你需要设置你ViewModelActivity/ Fragment.

以下是您可以学习MVVM架构的一些链接.

使用MVVM
Android MVVM 接近Android
https://github.com/ivacf/archi Android上的
People-MVVM
MVVM:你需要知道什么

  • 这些示例中的大多数在 ViewModel 中都有上下文引用。对我来说,这不是真正的 MVVM。 (3认同)
  • @MwBakker我相信关于MVVM的最重要的事情是各层之间的逻辑分离,因此,View应该负责处理UI,仅此而已!因此,在这种情况下,我认为具有对应用程序上下文的引用的视图模型比强制视图不执行任何UI任务的危害要小。顺便说一句,在其他许多情况下,我们可能需要在ViewModel中使用上下文,这就是Android具有版本的具有上下文的ViewModel的原因! (2认同)

gah*_*hfy 9

我的方法是在您的ViewModel中:

val activityToStart = MutableLiveData<Pair<KClass<*>, Bundle?>>()
Run Code Online (Sandbox Code Playgroud)

这使您可以检查启动的Activity的类以及在Bundle中传递的数据。然后,可以在“活动”中添加以下代码:

viewModel.activityToStart.observe(this, Observer { value ->
    val intent = Intent(this, value.first.java)
    if(value.second != null)
        intent.putExtras(value.second)
    startActivity(intent)
})
Run Code Online (Sandbox Code Playgroud)