【问题标题】:Best approach to start an Activity from ViewModel in MVVM Architecture在 MVVM 架构中从 ViewModel 启动 Activity 的最佳方法
【发布时间】:2018-08-23 20:03:48
【问题描述】:

我在应用程序中关注 MMVM 架构,一切正常,直到我使用以下代码从 ViewModel 启动活动时发生崩溃。使用数据绑定从 XML 调用方法并将view 作为参数传递,getApplication() 是来自AndroidViewModel 类的方法。

getApplication().startActivity(new Intent(view.getContext(), MyActivity.class));

我相信这是因为我没有使用 NEW_TASK 标志,因为我在 Activity 类之外开始活动。

现在我能想到以下解决方案,但从架构的角度来看,我不确定哪一个是最好的。

1. ViewModel 的方法以 Activity 为参数并从片段中调用该方法

public startMyActivity(Activity activity){
   activity.startActivity(new Intent(activity, MyActivity.class));
}

现在在片段中添加一个类似这样的监听器

mBinding.myButton.setOnClickListener(){
    viewModel.startMyActivity(getActivity());  
}

2。将新任务标志添加到意图并将其保留在 ViewModel 本身中

Intent myIntent = new Intent(view.getContext(), MyActivity.class);
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
getApplication().startActivity(myIntent);

3.从片段本身启动 Activity

mBinding.myButton.setOnClickListener(){
   activity.startActivity(new Intent(activity, MyActivity.class));
}

我相信所有这些方法都可以正常工作,但要考虑一个问题

是否可以在 Fragment 中单独设置侦听器以使用绑定的 ViewModels 从视图 xml 调用方法?

我不确定第二种方法是否仍会使应用在某些操作系统中崩溃。

从架构的角度和单元测试的角度来看,哪一个是最好的方法?

【问题讨论】:

  • 必须避免在 ViewModel 或 AndroidViewModel 中使用任何 android 视图。
  • @ChintanSoni 我同意,它不是从点击侦听器方法上的数据绑定传递的引用,我相信这应该没问题。
  • 是的,你是对的,这取决于,如果你有可用的活动上下文,那么最好使用,NEW_TASK 通常使用活动上下文不可用,例如在广播接收器或服务中等等

标签: android mvvm android-viewmodel android-mvvm


【解决方案1】:

我会在活动/片段中进行导航,但当然大多数情况下您想从视图模型触发导航。 因此,您需要使用视图模型中的命令来通知您的视图(活动/片段)在其他地方导航。 您可以使用 LiveData 执行这种“命令”,更具体地说是 SingleLiveEvent

SingleLiveEvent 与任何 LiveData 类似,但仅在您明确为其设置值时才会触发事件,例如,当您开始从视图(活动/片段)观察它时不会收到它的值

【讨论】:

  • 谢谢,我会试试看这是否适合我。
  • 如果我在当前屏幕上有很多可能的目的地。对于每个可能的目的地,我应该有 1 个SingleLiveEvent 吗?这方面的最佳做法是什么?
  • 我会选择一个事件和目的地作为参数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-02
  • 2013-01-24
相关资源
最近更新 更多