Android Architecture Components中关于各个组件职责的问题
Questions about the responsbilities of each component in Android Architecture Components
我已经使用 MVP 很长时间了,我开始过渡到 MVP 和 MVVM 之间的混合状态
详细来说,我的应用程序将如下所示:
- 每个 Activity 都有一个代表其观点的 0 到 x 片段
- 每个 Fragment 都将请求 Activity 的 ViewModel,以便它们可以使用 LiveData
检索数据
- Activity 将有一个单独的 ViewModel 作为演示者。在创建时,ViewModel 将被注入带有 LiveData 的 Activity 的 ViewModel,以便它可以根据需要更新 UI
- 演示者将获取发送到数据 ViewModel 的消息并将结果发回给它
我的问题:
- 在演示者 ViewModel 中持有对数据 ViewModel 的引用会导致内存泄漏或内存泄漏等不利影响吗?
- 业务逻辑应该放在哪里?在演示者中还是在模型部分?
例如,假设我有一个项目列表,用户长按一个来编辑它们,这个架构的哪一部分应该负责检查用户是否有权这样做,或者让他们编辑项或显示错误消息?
- 有没有办法让 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)
}
注意:我知道上面的代码不起作用,我想问的是是否有类似的方法可以工作
- 将消息发回 activity SingleEvents 的正确方法是正确的吗?
例如,如果用户试图删除一个条目,我希望他们输入密码,那么流程是:
- Fragment 将要删除的消息发送到它的 ViewModel
- ViewModel 将其传递给 Presenter
- 演示者决定在继续之前需要密码验证
- 演示者在 ViewModel 中设置 SingleEvent 的值
- ViewModel 通知事件的订阅者(在本例中为 MainActivity)他们应该显示一个要求输入密码的对话框
感谢您提供的任何帮助
我最近将我的一个应用程序从 MVP 移植到 MVVM 架构。不管你是部分地还是完全地做,你都在朝着伟大而干净的方向前进,你会喜欢它的。
在检查答案之前,请看一下这个 MVVM 架构图以及其中的一些注意事项
下面让我们看看每个类的作用。
Activity/Fragment:
-监听 MutableLiveData Obeservers 并将 Data 设置到视图,这里没有其他逻辑。
视图模型
- 用户输入验证(用户名、密码为空或空检查)
- 设置你的 mutableLive
- 要求存储库启动任务网络或本地数据存储(sqlite),带回调。
存储库
- 缓存所需数据。
- 不应保留对 ViewModel 的任何引用,这将创建循环依赖。
- 决定要做什么 - 是进行网络调用还是从本地存储加载数据。接收到的数据的操作在这里(业务逻辑)。
- 使用从 ViewModel 收到的回调将数据更新到 viewModel,严格禁止直接通信。
远程数据源
- 进行网络调用并将接收到的数据返回给存储库。
本地数据源
- 处理所有 SQLite 相关的东西,并通过回调提供请求的数据。
google 有一个使用 MVVM 的待办事项应用示例项目。请参考它,这将非常有帮助。
- 无演示者 - 检查视图模型上的用户输入并使用存储库进行交流,然后使用 MutableLiveData 进行交流。
- 在 Repository 中执行您的业务逻辑,将其视为 mvp 模式中的模型。
- 您的 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();
}
- 密码验证流程:
- 片段要求 ViewModel 删除条目。
- 要求存储库决定是否需要验证,使用我们已有的数据或与本地数据源通信。
- ViewModel 收到来自 Repository 的回调,表示需要验证,ViewModel 更新相应的 MutableLiveData showVerification.postValue(true);
- 由于 activity 正在监听 showVerificationObserver,它显示验证 UI。
希望对您有所帮助。
我已经使用 MVP 很长时间了,我开始过渡到 MVP 和 MVVM 之间的混合状态
详细来说,我的应用程序将如下所示:
- 每个 Activity 都有一个代表其观点的 0 到 x 片段
- 每个 Fragment 都将请求 Activity 的 ViewModel,以便它们可以使用 LiveData 检索数据
- Activity 将有一个单独的 ViewModel 作为演示者。在创建时,ViewModel 将被注入带有 LiveData 的 Activity 的 ViewModel,以便它可以根据需要更新 UI
- 演示者将获取发送到数据 ViewModel 的消息并将结果发回给它
我的问题:
- 在演示者 ViewModel 中持有对数据 ViewModel 的引用会导致内存泄漏或内存泄漏等不利影响吗?
- 业务逻辑应该放在哪里?在演示者中还是在模型部分?
例如,假设我有一个项目列表,用户长按一个来编辑它们,这个架构的哪一部分应该负责检查用户是否有权这样做,或者让他们编辑项或显示错误消息?
- 有没有办法让 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)
}
注意:我知道上面的代码不起作用,我想问的是是否有类似的方法可以工作
- 将消息发回 activity SingleEvents 的正确方法是正确的吗?
例如,如果用户试图删除一个条目,我希望他们输入密码,那么流程是:
- Fragment 将要删除的消息发送到它的 ViewModel
- ViewModel 将其传递给 Presenter
- 演示者决定在继续之前需要密码验证
- 演示者在 ViewModel 中设置 SingleEvent 的值
- ViewModel 通知事件的订阅者(在本例中为 MainActivity)他们应该显示一个要求输入密码的对话框
感谢您提供的任何帮助
我最近将我的一个应用程序从 MVP 移植到 MVVM 架构。不管你是部分地还是完全地做,你都在朝着伟大而干净的方向前进,你会喜欢它的。
在检查答案之前,请看一下这个 MVVM 架构图以及其中的一些注意事项
下面让我们看看每个类的作用。
Activity/Fragment:
-监听 MutableLiveData Obeservers 并将 Data 设置到视图,这里没有其他逻辑。
视图模型
- 用户输入验证(用户名、密码为空或空检查)
- 设置你的 mutableLive
- 要求存储库启动任务网络或本地数据存储(sqlite),带回调。
存储库
- 缓存所需数据。
- 不应保留对 ViewModel 的任何引用,这将创建循环依赖。
- 决定要做什么 - 是进行网络调用还是从本地存储加载数据。接收到的数据的操作在这里(业务逻辑)。
- 使用从 ViewModel 收到的回调将数据更新到 viewModel,严格禁止直接通信。
远程数据源
- 进行网络调用并将接收到的数据返回给存储库。
本地数据源
- 处理所有 SQLite 相关的东西,并通过回调提供请求的数据。
google 有一个使用 MVVM 的待办事项应用示例项目。请参考它,这将非常有帮助。
- 无演示者 - 检查视图模型上的用户输入并使用存储库进行交流,然后使用 MutableLiveData 进行交流。
- 在 Repository 中执行您的业务逻辑,将其视为 mvp 模式中的模型。
- 您的 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();
}
- 密码验证流程:
- 片段要求 ViewModel 删除条目。
- 要求存储库决定是否需要验证,使用我们已有的数据或与本地数据源通信。
- ViewModel 收到来自 Repository 的回调,表示需要验证,ViewModel 更新相应的 MutableLiveData showVerification.postValue(true);
- 由于 activity 正在监听 showVerificationObserver,它显示验证 UI。
希望对您有所帮助。