有关Android架构组件中每个组件的职责的问题

问题描述 投票:8回答:1

我已经使用MVP很长一段时间了,我开始转移到MVP和MVVM之间的混合状态

详细我的应用程序将如下所示:

  • 每个Activity都有一个0到x的片段来表示它的视图
  • 每个Fragment都会请求Activity的ViewModel,以便他们可以使用LiveData检索数据
  • Activity将有一个单独的ViewModel,它将充当演示者。在创建时,ViewModel将使用LiveData的ViewModel注入,以便它可以根据需要更新UI
  • 演示者将获取发送到数据ViewModel的消息并将结果发送回它

我的问题:

  1. 可以在演示者ViewModel中持有对数据ViewModel的引用导致内存泄漏或内存泄漏等不利影响吗?
  2. 业务逻辑应该在哪里?在演示者或模特部分?

例如,假设我有一个项目列表,用户长按一个来编辑它们,这个架构的哪个部分应该负责检查用户是否有权这样做并让他们编辑项目或显示错误信息?

  1. 片段有没有办法只获取Activity的ViewModel的一部分?

例如,假设活动下面有3个碎片,并且一个ViewModel可以满足它们

我可以使用类似的东西:

class MainViewModel : ViewModel() , IFragmentA, IFragmentB, IFragmentC

然后当我尝试在片段中获取ViewModel时,我可以编写如下内容:

lateinit var viewModel: IFragmentA

override fun onAttach(context: Context?) {
    super.onAttach(context)
    vm = ViewModelProviders.of(context as AppCompatActivity).get(IFragmentA::class.java)
}

注意:我知道上面的代码不起作用,我要问的是,是否有类似于此的方法可行

  1. 将消息发送回活动SingleEvents的正确方法是什么?

例如,如果用户尝试删除条目,并且我希望他们输入密码,那么流程是:

  • Fragment将消息发送到其ViewModel
  • ViewModel将其传递给Presenter
  • Presenter决定在继续之前需要密码验证
  • 演示者在ViewModel中设置SingleEvent的值
  • ViewModel通知事件的订阅者(在本例中为MainActivity),他们应该显示一个要求输入密码的对话框

感谢您提供任何帮助

android android-architecture-components android-mvp android-mvvm
1个回答
4
投票

我最近将我的一个应用程序从MVP移植到MVVM架构。无论你是部分地还是完全地做到这一点,你都会走向一个伟大而干净的东西,你会喜欢它。

在查看答案之前,请先看看这个MVVM架构图以及它的一些注意事项

MVVM Architecture

我们来看看每个类的角色。

Activity/Fragment:

-Listen到MutableLiveData Obeservers并将Data设置为视图,此处没有其他逻辑。

ViewModel

  • 用户输入验证(用户名,密码为空或空检查)
  • 设置你的mutableLive
  • 要求存储库启动任务网络或localdatastorage(sqlite),并带有回调。

Repository

  • 缓存所需数据。
  • 不应该持有任何对ViewModel的引用,这将创建一个循环依赖。
  • 决定做什么 - 是进行网络呼叫还是从本地存储加载数据。对所接收数据的操纵就在这里(业务逻辑)。
  • 使用从ViewModel收到的回调来更新数据到viewModel,严格没有直接通信。

RemoteDataSource

  • 进行网络呼叫并将收到的数据提供给存储库。

LocalDataSource

  • 处理所有与SQLite相关的东西,并通过回调提供所请求的数据。

有一个来自google的todo app示例项目,它使用MVVM。请参考,这将是非常有帮助的。

  1. 没有演示者 - 检查viewmodel上的用户输入,并使用MutableLiveData使用存储库和返回进行通信。
  2. 在存储库中执行业务逻辑,将其视为mvp模式中的模型。
  3. 您可以为您的活动及其片段设置单个viewModel。您的所有片段都通过一个viewModel进行通信。所以每个片段只会对它侦听的LiveDataObserver做出反应。

在MVVM的Google示例项目中实际上有一个这个用例的例子。

AddEditTaskActivity.java

public static AddEditTaskViewModel obtainViewModel(FragmentActivity activity) {
       // Use a Factory to inject dependencies into the ViewModel        
 ViewModelFactoryfactory= ViewModelFactory.getInstance(activity.getApplication());
 return ViewModelProviders.of(activity, factory).get(AddEditTaskViewModel.class);
   }

AddEditTaskFragment.java

 @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        final View root = inflater.inflate(R.layout.addtask_frag, container, false);
        if (mViewDataBinding == null) {
            mViewDataBinding = AddtaskFragBinding.bind(root);
        }

        mViewModel = AddEditTaskActivity.obtainViewModel(getActivity());

        mViewDataBinding.setViewmodel(mViewModel);
        mViewDataBinding.setLifecycleOwner(getActivity());

        setHasOptionsMenu(true);
        setRetainInstance(false);

        return mViewDataBinding.getRoot();
    }

  1. 密码验证流程: 片段请求ViewModel deleteEntry。 询问存储库,以确定是否需要验证,使用我们已有的数据或与本地数据源进行通信。 ViewModel接收来自Repository的回调说需要验证,ViewModel更新相应的MutableLiveData showVerification.postValue(true); 当活动正在侦听showVerificationObserver时,它会显示验证UI。

希望能帮助到你。

© www.soinside.com 2019 - 2024. All rights reserved.