android 安卓 mvp mvvm - mvp
android 安卓 mvp mvvm - mvvm
1.MVVM简介
MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。当然这些事 ViewModel 已经帮我们做了,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。微软的WPF带来了新的技术体验,如Silverlight、音频、视频、3D动画……,这导致了软件UI层更加细节化、可定制化。同时,在技术层面,WPF也带来了 诸如Binding、Dependency Property、Routed Events、Command、DataTemplate、ControlTemplate等新特性。MVVM(Model-View-ViewModel)框架的由来便是MVP(Model-View-Presenter)模式与WPF结合的应用方式时发展演变过来的一种新型架构框架。它立足于原有MVP框架并且把WPF的新特性糅合进去,以应对客户日益复杂的需求变化。
2.MVVM优点
MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大优点
1. 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
2. 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
3. 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,使用Expression Blend可以很容易设计界面并生成xaml代码。
4. 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。
3.MVVM流程图
4.android应用结构之viewModel
4.1ViewModel的生命周期
ViewModel生命长度是在获取ViewModel时传递给ViewModelProvider的对象的生命周期决定的。 ViewModel保留在内存中,直到说依赖的有生命周期的对象永久消失:在Activity的情况下,当它被FINISHED,而在Fragment的情况下,当它被DETACHED。
图中展示了一个活动在经历一个循环后的各种生命周期状态,然后结束。 该图还显示了相关活动生命周期旁边的ViewModel的生命周期。 这个特定的图表说明了一个活动的状态。 相同的基本状态适用于片段的生命周期。
Android framework管理UI控制器(如Activity和Fragment)的生命周期。 framework可能会决定销毁或重新创建UI控制器,以响应完全不受控制的某些用户操作或设备事件。
如果系统销毁或重新创建UI控制器,则存储在其中的所有临时的UI相关数据都将丢失。 举个例子,您的应用中的一个Activity可能包含用户列表。 当因配置更改重新创建Activity时,新Activity必须重新获取用户列表。 对于简单数据,活动可以使用onSaveInstanceState()方法并从onCreate()中的数据包中恢复其数据,但是此方法仅适用于可以序列化然后反序列化的少量数据,而不适用于潜在的大量数据,例如用户列表或位图。
另一个问题是UI控制器经常需要异步请求,需要一些时间才能获取结果。 UI控制器需要管理这些请求,确保在系统销毁自己时,清理这些请求以避免潜在的内存泄漏。 这种管理需要大量的维护代码,并且在因配置更改而重新创建UI控制器的时,可能不得不重新发出已经发出过的请求,这样会浪费许多资源。
UI控制器(如Activity和Fragment)主要用于显示UI数据,对用户操作做出响应,或处理与操作系统之间的通信(如权限请求)。 再让UI控制器负责从数据库或网络加载数据,会导致该类过度臃肿。 给UI控制器分配过多的工作,可能会导致一个类去单独处理应用程序的所有工作,而不是将工作委托给其他类。 给UI控制器分配过多的工作也使得测试工作变得更加困难。
将视图数据的所有权从UI控制器逻辑中分离出来,会让项目更简单,更高效。
4.2ViewModel的使用
Architecture Components为UI控制器提供了ViewModel助手类,以便给UI准备数据。
public class LoginViewModel extends ViewModel implements LoginCallBack, LoginMethodInterface {
private LoginMethod loginMethod;
private MutableLiveData<Integer> loginResult = new MutableLiveData<>();
public LoginViewModel() {
this.loginMethod = new LoginMethod(this);
}
public MutableLiveData<Integer> getLoginResult() {
return loginResult;
}
@Override
public void onUnsernameError() {
loginResult.setValue(1);
loginResult.setValue(4);
}
@Override
public void onPasswordError() {
loginResult.setValue(2);
loginResult.setValue(4);
}
@Override
public void onSuccess() {
loginResult.setValue(0);
}
@Override
public void login(String username, String password) {
loginResult.setValue(3);
loginMethod.login(username,password);
}
}
MutableLiveData<T>为对象的承载类,我觉得类似于接口回调函数,T为回调的对象
在Activity中通过 viewModel 来访问数据列表
public class LoginActivity extends AppCompatActivity implements LoginView {
private LoginViewModel viewModel;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel= ViewModelProviders.of(this).get(LoginViewModel.class);
viewModel.getLoginResult().observe(this, new Observer<Integer>() {
@Override
public void onChanged(Integer integer) {
switch (integer){
case 0:
startActivity(new Intent(LoginActivity.this,MainActivity.class));
break;
case 1:
username.setError(getString(R.string.username_error));
break;
case 2:
password.setError(getString(R.string.password_error));
break;
case 3:
progressBar.setVisibility(View.VISIBLE);
break;
case 4:
progressBar.setVisibility(View.GONE);
break;
}
}
5 MVP与MVVM区别
ViewModel与View绑定后,ViewModel与View其中一方的数据更新都能立即通知到对方;Presenter需要通过接口去通知View进行更新。
6 MVVM的缺点
数据绑定使得程序较难调试,界面出现异常时,有可能是 View 的代码有问题,也可能是 Model 的代码有问题。由于数据绑定使得数据能够快速传递到其他为止,因此要定位出异常就比较有难度了。
个人认为MVP 与MVVM的用法其实差不多的,一个通过接口传输数据,一个通过viewModel传输数据,具体使用还是需要实际使用情况而定
以下是我写的简单的demo地址 mvvm与mvp写一块了
demo地址