Android MVP架构从入门到精通-真枪实弹

本文介绍了Android开发中从MVC到MVP架构的转变,分析了MVC的优缺点,并详细阐述了MVP架构模式,包括其优缺点、工作流程、实战应用,以及如何优化MVP架构,实现P层复用和处理多网络请求。此外,提供了完整的MVP项目源码链接供读者参考学习。
摘要由CSDN通过智能技术生成

一. 前言

你是否遇到过Activity/Fragment中成百上千行代码,完全无法维护,看着头疼?

你是否遇到过因后台接口还未写而你不能先写代码逻辑的情况?

你是否遇到过用MVC架构写的项目进行单元测试时的深深无奈?

如果你现在还是用MVC架构模式在写项目,请先转到MVP模式!

二. MVC架构

MVC架构模式最初生根于服务器端的Web开发,后来渐渐能够胜任客户端Web开发,再后来因Android项目由XML和Activity/Fragment组成,慢慢的Android开发者开始使用类似MVC的架构模式开发应用.

mvc架构模式

M层:模型层(model),主要是实体类,数据库,网络等存在的层面,model将新的数据发送到view层,用户得到数据响应.

V层:视图层(view),一般指XML为代表的视图界面.显示来源于model层的数据.用户的点击操作等事件从view层传递到controller层.

C层:控制层(controller),一般以Activity/Fragment为代表.C层主要是连接V层和M层的,C层收到V层发送过来的事件请求,从M层获取数据,展示给V层.

从上图可以看出M层和V层有连接关系,而Activity有时候既充当了控制层又充当了视图层,导致项目维护比较麻烦.

1. MVC架构优缺点
A. 缺点
  1. M层和V层有连接关系,没有解耦,导致维护困难.

  2. Activity/Fragment中的代码过多,难以维护.

Activity中有很多关于视图UI的显示代码,因此View视图和Activity控制器并不是完全分离的,当Activity类业务过多的时候,会变得难以管理和维护.尤其是当UI的状态数据,跟持久化的数据混杂在一起,变得极为混乱.

B. 优点
  1. 控制层和View层都在Activity中进行操作,数据操作方便.

  2. 模块职责划分明确.主要划分层M,V,C三个模块.

三. MVP架构

MVP

MVP,即是Model,View,Presenter架构模式.看起来类似MVC,其实不然.从上图能看到Model层和View层没有相连接,完全解耦.

用户触碰界面触发事件,View层把事件通知Presenter层,Presenter层通知Model层处理这个事件,Model层处理后把结果发送到Presenter层,Presenter层再通知View层,最后View层做出改变.这是一整套流程.

M层:模型层(Model),此层和MVC中的M层作用类似.

V层:视图层(View),在MVC中V层只包含XML文件,而MVP中V层包含XML,Activity和Fragment三者.理论上V层不涉及任何逻辑,只负责界面的改变,尽量把逻辑处理放到M层.

P层:通知层(Presenter),P层的主要作用就是连接V层和M层,起到一个通知传递数据的作用.

1. MVP架构优缺点
A. 缺点
  1. MVP中接口过多.

  2. 每一个功能,相比于MVC要多写好几个文件.

  3. 如果某一个界面中需要请求多个服务器接口,这个界面文件中会实现很多的回调接口,导致代码繁杂.

  4. 如果更改了数据源和请求中参数,会导致更多的代码修改.

  5. 额外的代码复杂度及学习成本.

B. 优点
  1. 模块职责划分明显,层次清晰,接口功能清晰.

  2. Model层和View层分离,解耦.修改View而不影响Model.

  3. 功能复用度高,方便.一个Presenter可以复用于多个View,而不用更改Presenter的逻辑.

  4. 有利于测试驱动开发,以前的Android开发是难以进行单元测试.

  5. 如果后台接口还未写好,但已知返回数据类型的情况下,完全可以写出此接口完整的功能.

四. MVP架构实战(真枪实弹)
1. MVP三层代码简单书写

接下来笔者从简到繁,一点一点的堆砌MVP的整个架构.先看一下XML布局,布局中一个Button按钮和一个TextView控件,用户点击按钮后,Presenter层通知Model层请求处理网络数据,处理后Model层把结果数据发送给Presenter层,Presenter层再通知View层,然后View层改变TextView显示的内容.

MVP

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".view.SingleInterfaceActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="点击" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100px"
        android:text="请点击上方按钮获取数据" />
</LinearLayout>

接下来是Activity代码,里面就是获取Button和TextView控件,然后对Button做监听,先简单的这样写,一会慢慢的增加代码.

public class SingleInterfaceActivity extends AppCompatActivity {

    private Button button;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_single_interface);
        button = findViewById(R.id.button);
        textView = findViewById(R.id.textView);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });

    }
}

下面是Model层代码.本次网络请求用的是wanandroid网站的开放api,其中的文章首页列表接口.SingleInterfaceModel文件里面有一个方法getData,第一个参数curPage意思是获取第几页的数据,第二个参数callback是Model层通知Presenter层的回调.

public class SingleInterfaceModel {
    
    public void getData(int curPage, final Callback callback) {
        NetUtils.getRetrofit()
                .create(Api.class)
                .getData(curPage)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<ArticleListBean>() {
                    @Override
                    public void onCompleted() {
                        LP.w("completed");
                    }

                    @Override
                    public void onError(Throwable e) {
                        callback.onFail("出现错误");
                    }

                    @Override
                    public void onNext(ArticleListBean bean) {
                        if (null == bean) {
                            callback.onFail("出现错误");
                        } else if (bean.errorCode != 0) {
                            callback.onFail(bean.errorMsg);
                        } else {
                            ca
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值