Android 技术架构
1.Android技术架构有哪几种
- MVC
- MVC全名是Model View Controller,如图,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
- MVP
- MVP从更早的MVC框架演变过来,与MVC有一定的相似性:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。
- MVVM
2.MVC架构简单介绍
2.1 MVC介绍
- Model View Controller,是软件架构中最常见的一种框架,简单来说就是通过controller的控制去操作model层的数据,并且返回给view层展示,具体见下图
- 工作原理
- 当用户出发事件的时候,view层会发送指令到controller层,接着controller去通知model层更新数据,model层更新完数据以后直接显示在view层上,这就是MVC的工作原理。
- M层处理数据,业务逻辑等
- V层处理界面的显示结果
- C层起到桥梁的作用,来控制V层和M层通信以此来达到分离视图显示和业务逻辑层
- 当用户出发事件的时候,view层会发送指令到controller层,接着controller去通知model层更新数据,model层更新完数据以后直接显示在view层上,这就是MVC的工作原理。
2.2 Android实际应用场景
- 视图层(View)
- 一般采用XML文件进行界面的描述,这些XML可以理解为AndroidApp的View。使用的时候可以非常方便的引入。同时便于后期界面的修改。逻辑中与界面对应的id不变化则代码不用修改,大大增强了代码的可维护性。
- 控制层(Controller)
- Android的控制层的重任通常落在了众多的Activity的肩上。这句话也就暗含了不要在Activity中写代码,要通过Activity交割Model业务逻辑层处理,这样做的另外一个原因是Android中的Actiivity的响应时间是5s,如果耗时的操作放在这里,程序就很容易被回收掉。
- 模型层(Model)
- 针对业务模型,建立的数据结构和相关的类,就可以理解为AndroidApp的Model,Model是与View无关,而与业务相关的。对数据库的操作、对网络等的操作都应该在Model里面处理,当然对业务计算等操作也是必须放在的该层的。就是应用程序中二进制的数据。
- 对于Android工程,有Java的class文件,有res文件夹,里面是各种资源,还有类似manifest文件等等。
对于原生的Android项目来说,- layout.xml里面的xml文件就对应于MVC的view层,里面都是一些view的布局代码,
- 而各种Java bean,还有一些类似repository类就对应于model层,
- 至于controller层嘛,当然就是各种activity咯。
- 大家可以试着套用我上面说的MVC的工作原理是理解。比如你的界面有一个按钮,按下这个按钮去网络上下载一个文件,这个按钮是view层的,是使用xml来写的,而那些和网络连接相关的代码写在其他类里,比如你可以写一个专门的networkHelper类,这个就是model层,那怎么连接这两层呢?是通过button.setOnClickListener()这个函数,这个函数就写在了activity中,对应于controller层。是不是很清晰。
2.3 MVC缺陷
- 问题就在于xml作为view层,控制能力实在太弱了,你想去动态的改变一个页面的背景,或者动态的隐藏/显示一个按钮,这些都没办法在xml中做,只能把代码写在activity中,造成了activity既是controller层,又是view层的这样一个窘境。
- MVC还有一个重要的缺陷,大家看上面那幅图,view层和model层是相互可知的,这意味着两层之间存在耦合,耦合对于一个大型程序来说是非常致命的,因为这表示开发,测试,维护都需要花大量的精力。
- Activity并不是一个标准的MVC模式中的Controller,它的首要职责是加载应用的布局和初始化用户 界面,并接受并处理来自用户的操作请求,进而作出响应。随着界面及其逻辑的复杂度不断提升,Activity类的职责不断增加,以致变得庞大臃肿。
2.4 MVC最简单的例子
2.4.1 Model层
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//接口
public interface InterModel {
void getAboutData(AboutDataListener<OnlineMusicList> listener);
}
/**
* 数据model类
*/
public class MeAboutModel implements InterModel {
@Override
public void getAboutData(final AboutDataListener<OnlineMusicList> listener) {
//开始请求网络
OnLineMusicModel model = OnLineMusicModel.getInstance();
model.getList(OnLineMusicModel.METHOD_LINE_MUSIC , "", 0 ,3)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<OnlineMusicList>() {
@Override
public void accept(OnlineMusicList onlineMusicList) throws Exception {
listener.onSuccess(onlineMusicList);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
listener.onError();
}
}, new Action() {
@Override
public void run() throws Exception {
}
});
}
}2.4.2 Controllor(View)层
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
33public class MeAboutActivity extends BaseActivity {
@Override
public int getContentView() {
return R.layout.activity_me_about;
}
@Override
public void initView() {
}
@Override
public void initListener() {
}
@Override
public void initData() {
MeAboutModel mvpModel = new MeAboutModel();
mvpModel.getAboutData(new AboutDataListener<OnlineMusicList>() {
@Override
public void onSuccess(OnlineMusicList onlineMusicList) {
}
@Override
public void onError() {
}
});
}
}简单分析下这个例子:
1、activity里面的控件必须关心业务和数据,才能知道自己怎么展示。换句话说,我们很难让两个人在不互相沟通的情况下,一人负责获取数据,一人负责展示UI,然后完成这个功能。
2、所以的逻辑都在activity里面。完美的体现了MVC的两大缺点:View对Model的依赖,会导致View也包含了业务逻辑;Controller会变得很厚很复杂。
3.MVP架构简单介绍
3.1 MVP简单介绍
- MVP作为MVC的演化,解决了MVC不少的缺点,对于Android来说,MVP的model层相对于MVC是一样的,而activity和fragment不再是controller层,而是纯粹的view层,所有关于用户事件的转发全部交由presenter层处理。
3.2 MVP工作原理
- MVP框架由3部分组成:View负责显示,Presenter负责逻辑处理,Model提供数据。在MVP模式里通常包含3个要素(加上View interface是4个):
- View:负责绘制UI元素、与用户进行交互(在Android中体现为Activity)
- Model:负责存储、检索、操纵数据(有时也实现一个Model interface用来降低耦合)
- Presenter:作为View与Model交互的中间纽带,处理与用户交互的负责逻辑。
- View interface:需要View实现的接口,View通过View interface与Presenter进行交互,降低耦合,方便进行单元测试
- 从图中就可以看出,最明显的差别就是view层和model层不再相互可知,完全的解耦,取而代之的presenter层充当了桥梁的作用,用于操作view层发出的事件传递到presenter层中,presenter层去操作model层,并且将数据返回给view层,整个过程中view层和model层完全没有联系。看到这里大家可能会问,虽然view层和model层解耦了,但是view层和presenter层不是耦合在一起了吗?其实不是的,对于view层和presenter层的通信,我们是可以通过接口实现的,具体的意思就是说我们的activity,fragment可以去实现实现定义好的接口,而在对应的presenter中通过接口调用方法。不仅如此,我们还可以编写测试用的View,模拟用户的各种操作,从而实现对Presenter的测试。这就解决了MVC模式中测试,维护难的问题。
- 当然,其实最好的方式是使用fragment作为view层,而activity则是用于创建view层(fragment)和presenter层(presenter)的一个控制器。
3.3 MVP最简单的例子
3.3.1 首先来看两个Base接口类
- BaseView与BasePresenter,两类分别是所有View和Presenter的基类。
1
2
3
4
5
6
7
8
9
10
11
12public interface BaseView {
}
public interface BasePresenter {
//绑定数据
void subscribe();
//解除绑定
void unSubscribe();
}3.3.2 定义了契约类(接口)
- 也就是contract接口类,主要是activity和presenter中起到桥接作用
- 使用契约类来统一管理view与presenter的所有的接口,这种方式使得view与presenter中有哪些功能,一目了然,维护起来也很方便。
- AppContract中的View接口定义了该界面(功能)中所有的UI状态情况,AppActivity作为View层,实现了该接口,如此AppActivity只关注UI相关的状态更新,所有事件操作都调用AppPresenter来完成。
- Presenter 接口则定义了该界面(功能)中所有的用户操作事件,AppPresenter作为Presenter层,实现了该接口,如此AppPresenter则只关注业务层的逻辑相关,UI的更新只需调用View的状态方法。
1
2
3
4
5
6
7
8
9
10
11//contract起到桥接的作用
public interface AppContract {
interface View extends BaseView {
void setDataView();
}
interface Presenter extends BasePresenter {
void getData();
}
}3.3.3 Activity在mvp中的作用
- Activity在项目中是一个全局的控制者,负责创建view以及presenter实例,并将二者联系起来。AppActivity的onCreate()回调中创建并绑定AppPresenter实例,AppPresenter的构造函数中实现了View和Presenter的关联。
- 然后代码如下所示
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
47
48
49
50
51
52public class AppActivity extends AppCompatActivity implements AppContract.View{
private AppContract.Presenter mPresenter = new AppPresenter(this);
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_five);
mPresenter.subscribe();
mPresenter.getData();
}
@Override
protected void onDestroy() {
super.onDestroy();
if(mPresenter!=null){
mPresenter.unSubscribe();
}
}
@Override
public void setDataView() {
}
}
//persenter
public class AppPresenter implements AppContract.Presenter {
private AppContract.View mView;
public AppPresenter(AppContract.View androidView) {
this.mView = androidView;
}
@Override
public void subscribe() {
}
@Override
public void unSubscribe() {
}
//从网络获取数据
@Override
public void getData() {
mView.setDataView();
}
}
4.MVVM架构简单介绍
4.1 MVVM简单介绍
4.2 MVVM工作原理
从图中看出,它和MVP的区别貌似不大,只不过是presenter层换成了viewmodel层,还有一点就是view层和viewmodel层是相互绑定的关系,这意味着当你更新viewmodel层的数据的时候,view层会相应的变动ui。
5.三者之间比较
- MVP模式是从MVC模式演变来的,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示,所以他们之间并没有特别大的不同,都是用来将View和Model之间松耦合。作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中是允许Model和View进行交互的。还有重要的一点就是Presenter与View之间的交互是通过接口的。MVVM是通过MVP演变而来的,主要用了data binding来实现双向交互,这就使得视图和控制层之间的耦合程度进一步降低,关注点分离更为彻底,同时减轻了Activity的压力。
- 关键点总结:
- MVC
- Controller是基于行为,并且能够在view之间共享
- Controller负责接收用户交互等操作,并且决定需要显示的视图。
- MVP
- View和Model更加的解耦了,Presenter负责绑定Model到View。
- 复杂的View可以对应多个Persenter。
- Presenter保留有View层的事件逻辑,所有的点击之类的事件都直接委托给Presenter。
- Presenter通过接口直接和View层解耦,所以更加方便的进行View的单元测试。
- Presenter和其他两层都是双向调用的。
- MVP有两种实现方式:”Passive View”,View基本包含0逻辑, Presenter作为View和Model的中间人,View和Model相互隔离,View和Model没有直接的数据绑定,取而代之的是View提供相关的setter方法供Persenter去调用,这么做的好处是View和Model干净的分离开了,所以更好的进行相关测试,缺点是需要提供很多的setter方法;”Supervising Controller”,Persenter处理用户交互等的操作,View和Model直接通过数据绑定连接,这种模式下,Persenter的任务就是将实体直接通过Model层传递给View层,这种方法的好处就是代码量少了,但是缺点就是测试难度增大,并且View的封装性变低。
- MVVM
- 用户直接交互的是View。
- View和ViewModel是多对一的关系。
- View有ViewModel的引用,但是ViewModel没有任何关于View的信息。
- 支持View和ViewModel的双向数据绑定。
6.如何设计一个靠谱MVP架构
6.1 什么是MVP?什么是MVC?
1 | 1、什么是MVP? |
6.2 开始进行MVP搭建
1 | 内容一:MVP入门? |
6.3 优化工作介绍
1 | 代理一: |