android mvp mvvm区别,MVVM的实现以及与MVP的对比

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

在接触MVP之后也了解了MVVM的部分,当时DataBinding还未成熟,也就没有细致的看过,而现在DateBinding也已经很完善,相比较于MVP我更加推荐使用MVVM进行开发,而其也需要搭配一些其他的几个框架,首先就是他的本质框架,DataBinding,而还有一个也非常合适于MVVM和MVP的框架,Dagger2。

关于Dagger2的部分之后再单独进行介绍。

MVVM架构思想M(Model):控制着架构上的逻辑等的实体模型。

VM(ViewModel):与mvp不同的是ViewModel也是中间桥梁,但他并不需要契约类进行连接,而是使用DataBinding着一框架进行单向或双向的绑定。

V(View):代表着Activity与xml的ui界面内容。

MVVM的关键思想还是在于数据绑定,原本的mvc或是mvp每次的ui更新,其上的数据也需要随着变化都是从代码中跟随逻辑进行变化,而使用MVVM将使控件与其需要的内容进行绑定,每一次的数据更新将自动进行ui的更新。

依旧还是需要动手实践一下:

准备工作

MVVM框架由谷歌推荐,所以也拥有它特别的位置,从databinding开启的位置就可以看出来:

在gradle文件中添加下面几行代码即可开启databinding:1

2

3dataBinding {

enabled true

}

非常简单的开启方式。

xml界面1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

name="article"

type="DataBean"/>

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

tools:context="com.xblydxj.mvvmdemo.MainActivity">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="@[email protected]/time + article.date.curr}"

android:layout_margin="5dp"/>

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="@[email protected]/author + article.author}"

android:layout_margin="5dp"/>

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="@[email protected]/title + article.title}"

android:layout_margin="5dp"/>

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="@[email protected]/digest + article.digest}"

android:layout_margin="5dp"/>

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:text="@[email protected]/content + article.content}"

android:layout_margin="5dp"/>

xml的变化非常明显,首先最外层的包裹已经变化了,根节点为标签,而上方使用标签将本页面所需要的内容提供出来,下方即为正常的ui界面。

bean的提供

根据每日一文的json提供,我们先写出他对应的bean类:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16public class{

public DataBean data;

public static class DataBean{

public DateBean date;

public String author;

public String title;

public String digest;

public String content;

public int wc;

public static class DateBean{

public String curr;

public String prev;

public String next;

}

}

}

去除了一些set,get方法,改为public,以便调用。

转向xml部分:

在上部分的data标签中,我们需要提供变量,以供显示:1

2

3

4

5

6

name="article"

type="DataBean"/>

在其中使用import标签注入,在定义一个变量以供调用。

而下方每一个用于显示内容的textview,其text的显示属性将上方提供的数据进行绑定:1android:text="@{article.content}"

用于显示bean中content内容的TextView也将上方data提供的article中的content进行绑定,格式也真是这样。

Activty部分

这一部分完成双向绑定的工作,但和mvp不同的是,由于大部分ui是由数据控制进行改变的,所以mvvm中的activity已经节省了许多工作,所以这里的activity也包含着model层的工作,依旧是集中的。

其实这一点是值得吐槽的:MVP架构整体的解耦非常彻底,但是用于工程时很明显的一个弊端就是,类文件增加翻倍,而mvvm并没有这样的问题,他更自由。

这里为了方便,我再gradle中添加了rxjava与retrofit的依赖用于网络请求部分的编写。1

2

3

4

5

6

7

8compile 'com.squareup.okhttp3:okhttp:3.4.1'

compile 'com.squareup.okio:okio:1.9.0'

compile 'io.reactivex:rxandroid:1.2.1'

compile 'io.reactivex:rxjava:1.2.1'

compile 'com.artemzin.rxjava:proguard-rules:1.2.1.0'

compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'

compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'

compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'

在进行activity书写前,我们确保了xml文件的正确性,在studio中提前进行一次编译,这时databinding将为我们生成一个文件,原xml文件名为:activity_main.xml 而对应的生成的类文件名即为:ActivityMainBinding。1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27public class MainActivity extends AppCompatActivity{

ActivityMainBinding mBinding;

Api mRetrofit = new Retrofit.Builder()

.baseUrl("https://interface.meiriyiwen.com/")

.addConverterFactory(GsonConverterFactory.create())

.client(new OkHttpClient.Builder().build())

.addCallAdapterFactory(RxJavaCallAdapterFactory.create())

.build()

.create(Api.class);

protected void onCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);

mRetrofit.getArticle()

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Action1() {

public void call(Article article){

mBinding.setArticle(article.data);

}

});

}

}

如上,非常的精简,除了绑定部分的两行代码以外,剩余部分都是网络请求的一些初始化,一些mvc和mvp中需要做的关于ui与数据的显示已经全部由databinding帮我们做了。

在activity中首先我们在onCreate里去除了原有的setContentView的这行代码,而改为:1ActivityMainBinding mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);

抽取为成员变量以便调用。这一步即是替代了原有的setContentView。

之后便是直接开始retrofit的网络请求部分,先进行他的api定义:1

2

3

4public interface Api{

@GET("article/today")

Observable getArticle();

}

后续步骤就在activity中进行,成员变量的初始化,然后由retrofit进行请求,之后再在订阅成功后的next中将databinding需要的数据提供给他:1mBinding.setArticle(article.data);

这样即完成了一个简单的MVVM的构建。

总结

一个比较关键的使用,是关于recyclerview或是listview在这里的使用。databinding的recyclerview部分有些麻烦,但思想依旧是相同的,具体可以看这篇博客:精通DataBinding

但说回来,再某些时候,如果觉得使用databinding不熟练或是不方便,可以立马就转回原有的mvc写法,只是数据的部分再次归还给了activity,但不影响我们项目整体的编写。

如今databinding已经成熟,从项目的角度讲,相比较于MVP我更加推荐MVVM的写法。ui与逻辑的分离更加彻底。并且没有更多的文件增加。熟练掌握databinding之后会很舒服。

你可能感兴趣的:(android,mvp,mvvm区别)