Android Architecture Components中关于各个组件职责的问题

Questions about the responsbilities of each component in Android Architecture Components

我已经使用 MVP 很长时间了,我开始过渡到 MVP 和 MVVM 之间的混合状态

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

我的问题:

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

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

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

例如,假设 activity 下面有 3 个 Fragment,以及一个 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. 将消息发回 activity SingleEvents 的正确方法是正确的吗?

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

感谢您提供的任何帮助

我最近将我的一个应用程序从 MVP 移植到 MVVM 架构。不管你是部分地还是完全地做,你都在朝着伟大而干净的方向前进,你会喜欢它的。

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

下面让我们看看每个类的作用。

Activity/Fragment:

-监听 MutableLiveData Obeservers 并将 Data 设置到视图,这里没有其他逻辑。

视图模型

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

存储库

  • 缓存所需数据。
  • 不应保留对 ViewModel 的任何引用,这将创建循环依赖。
  • 决定要做什么 - 是进行网络调用还是从本地存储加载数据。接收到的数据的操作在这里(业务逻辑)。
  • 使用从 ViewModel 收到的回调将数据更新到 viewModel,严格禁止直接通信。

远程数据源

  • 进行网络调用并将接收到的数据返回给存储库。

本地数据源

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

google 有一个使用 MVVM 的待办事项应用示例项目。请参考它,这将非常有帮助。

  1. 无演示者 - 检查视图模型上的用户输入并使用存储库进行交流,然后使用 MutableLiveData 进行交流。
  2. 在 Repository 中执行您的业务逻辑,将其视为 mvp 模式中的模型。
  3. 您的 activity 及其片段可以有单个 viewModel。您所有的片段都通过一个 viewModel 进行通信。所以每个 Fragment 只会对它监听的 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 删除条目。
    • 要求存储库决定是否需要验证,使用我们已有的数据或与本地数据源通信。
    • ViewModel 收到来自 Repository 的回调,表示需要验证,ViewModel 更新相应的 MutableLiveData showVerification.postValue(true);
    • 由于 activity 正在监听 showVerificationObserver,它显示验证 UI。

希望对您有所帮助。