MVVM 模式是什么
MVVM即Model-View-ViewModel的缩写,它的出现是为了将图形界面与业务逻辑、数据模型进行解耦,MVVM架构的应用程序采用了数据模型驱动界面更新的设计方案,即当数据发生变化时,界面能够自动得到通知并进行更新。MVVM是Google官方推崇的一种Android项目架构模型。
Model
Repository及其下方就是Model了。Repository负责提取和处理数据。数据可以来自本地数据库(Room),也可以来自网络,这些数据统一有Repository处理,对应隐藏数据来源及获取方式。
View(Activity/Fragment)
显而易见,Activity/Fragment 便是MVVM中的View,当收到ViewModel传递来的数据时,Activity/Fragment负责将数据以你喜欢的方式显示出来。
ViewModel
解耦性强
Viewmodel其实就是activity中一个普通的实体。Activity持有viewmodel的引用,业务逻辑在viewmodel进行,关于界面和ui的操作在activity中进行,而添加和释放资源和viewmodel有关的那么就在viewmodel中设置函数,然后在activity中调用。ViewModel作为Activity/Fragment与其他组件的连接器,负责转换和聚合Model中返回的数据,使这些数据易于显示,并把这些数据改变及时的通知给Activity/Fragment。多个组件共享viewmodel
ViewModel可以很方便的在同一个Activity中多个Fragment中共享,只需要在ViewModelProviders.of(activity)时传入Fragment所在的Activity实例即可。保存数据功能更强大
相比于 onSaveInstanceState 、序列化等保存UI状态的方法,ViewModel更加轻量级,也能高性能的存储复杂类型的数据。
View与ViewModel如何实现自动刷新数据?
View层与ViewModel层的通信是通过LiveData这个架构组件实现的,不同于MVP架构中通过接口来通信。
Android中的数据绑定技术由 DataBinding和LiveData共同实现。当Activity/Fragment接收到来自ViewModel中的新数据时,由LiveData自动通知数据的改变,将这些数据通过DataBinding绑定到ViewDataBinding中,UI将会自动刷新,而不用书写类似setText的方法。随即DataBinding和LiveData闪亮登场。
DataBinding
Databing是Google发布的一个用来支持MVVM模式的框架,它的主要作用是用来降低布局和逻辑的耦合度。省去了各个findViewById,当viewmodel层数据更新,UI也会随即更新。
DataBinding可以做数据绑定,事件绑定,相应类的import,可以引入Java类或自定义类。
LiveData
LiveData是具有生命周期意识的一个可观察的的数据持有者,ViewModel中的数据由LiveData持有,并且只有当Activity/Fragment处于活动时才会通知UI数据的改变,避免无用的刷新UI;
它提供一个泛型来包装数据,它允许应用中的组建来观察LiveData中对象的变化。更进一步来讲,LiveData将数据的生产者与数据的消费者进行了分离。
LiveData特点:
1.首先LiveData其实与数据实体类是一样的东西,它负责暂存数据.
2.其次LiveData其实也是一个观察者模式的数据实体类,它可以跟它注册的观察者回调数据是否已经更新.
3.LiveData还能知晓它绑定的Activity或者Fragment的生命周期,它只会给前台活动的activity回调,避免组件销毁后发生意想不到的崩溃情况。
LiveData与MutableLiveData区别
1.MutableLiveData的父类是LiveData。
2.LiveData在实体类里可以通知指定某个字段的数据更新。MutableLiveData则是完全是整个实体类或者数据类型变化后才通知,不会细节到某个字段。
简单例子实现livedata的局部更新通知:
public class UserBean extends LiveData<UserBean> {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
postValue(this);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
postValue(this);
}
}
viewModel.getUserBean().setName("你的名字");
viewModel.getUserBean().observe(this, new Observer<UserBean>() {
@Override
public void onChanged(UserBean userBean) {
Log.i("TAG", "数据有更新");
}
});
LiveData类的方法:
setValue() :必须从主线程调用此方法,设置值给它的观察者
postValue():此方法可以在其他线程中调用
removeObserver(): 移除指定观察者
removeObservers():移除所有观察者
observeForever():设置永久观察者
Lifecycle
Lifecycle贯穿了LiveData与Viewmodel的使用过程,Lifecycle是Google官方提供的方便管理生命周期事件的方式,可以让我们的自定义组件更方便的监听生命周期变化事件,它以注解的方式作用在方法上,当系统组件生命周期方法调用时,它会随即将事件分发给各个自定义组件。
问题来了:
-
MVVM的缺点
1.数据绑定使得 Bug 不易调试,也会使得一个位置的 Bug 被快速传递到别的位置。
2.虽然使用Model方便了保证数据一致性,但是大的模块中长期不释放内存就会造成花费更多的内存。
3.不利于代码重用。客户端开发最常用的重用是View,但是在一个View都绑定了一个model,不同模块的model都不同。那就不能简单重用View了。
-
Mvp模式的缺点是什么
MVP优点:
代码结构更清晰,减少了acvitity的职责,简化了acvitity中的代码,
将复杂的逻辑代码提取到了Presenter类中执行,让model和view完全解耦,耦合度更低。可以复用Presenter。
MVP缺点:
视图和Presenter的交互会过于频繁,使得他们的联系过于紧密。也就是说,一旦视图变更了,presenter也要变更。
使用mvp模式会将类的数量扩增,需要创建额外的view类和presenter类。
由于Presenter经常性的需要执行一些耗时操作,那么当我们在操作未完成时候关闭了Activity,会导致Presenter一直持有Activity的对象,造成内存泄漏。
需要在baseActivity或者在baseFragment的onDestroy回调中调用BasePresenter的detachView()
解除关联。
public abstract class BasePresenter<T> {
protected Reference<T> mViewRef;//View接口类型弱引用
public void attachView(T view) {
mViewRef = new WeakReference<T>(view); //建立关联
}
protected T getView() {
return mViewRef.get();//获取View
}
public boolean isViewAttached() {//判断是否与View建立了关联
return mViewRef != null && mViewRef.get() != null;
}
public void detachView() {//解除关联
if (mViewRef != null) {
mViewRef.clear();
mViewRef = null;
}
}
}
``