文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

AndroidMVP模式面向接口写法

2023-05-20 05:23

关注

首先我们需要知道mvp所代表的含义,m即model可以理解成用来获取数据和处理数据,v即view可以看成activity和fragment用来显示数据和处理交互,p即presenter可以理解成用来提供数据。

三者关系:m层用来获取数据然后将数据提供给p层,p层拿到数据后通过v层展示,其中m层和v层是不能直接进行交互的,通过p层这个桥梁进行交互。这其中p层会持有v层和m层的引用。(先读懂)

理解上面的说法下面我们直接上手代码:

为了减少接口文件我们可以把接口都声明在Contract内

public interface ContentContract {
    interface Model {
    }
    interface View {
    }
    interface Presenter {
    }
}
//这样我们不需要写三个接口文件

然后分别实现三个接口与之对应的m层,v层,p层

//model
public class ContentModel implements ContentContract.Model {
}
//view
public class MainActivty extends BaseQuickActivty implements ContentContract.View {
}
//presenter
public class ContentPresenter implements ContentContract.Presenter {
}

首先我们需要考虑的是在v层我们需要做一些什么处理,然后在定义我们的方法。假如我们需要获取首页的banner数据,这时候就可以在view中声明一个方法用来接收banner数据。

public interface ContentContract {
    interface Model {
    }
    interface View {
    void getBanner(String str);
    }
    interface Presenter {
    }
}
//这时候activity实现此方法
public class MainActivty extends BaseQuickActivty implements ContentContract.View {
    @Override
    public void getBanner(String  str) {
    }
}

当v层已经有了接收数据的方法时,那么数据从何而来了?我们在之前说过m层是用来获取数据的 所以我们可以在m层中定义一个请求网络的方法。

//
public class ContentModel implements ContentContract.Model {
      //获取banner
     public void sendHttpBannerData(OnListener<String> on){
          //这里需要考虑一个问题,就是每次获取请求后的数据,我们需要传递给p层,所以需要一个回调处理
          //我们可以对m层进一步封装下
          //代码示例  
          okgo.post().ex(new CallBack(){
             public void onSucces(String str){
                    on.onSuccess(str);
              }
              public void onFail(){
                     on.onFail();
              }
             });
   }
}
//封装后的modle层  ,先提取一个基类BaseModel
public interface BaseModel<T> {
    interface OnListener<T> {
        void onSuccess(T t);
        void onFail(int code, String msg);
    }
}
//modle实现
 interface Model<T> extends BaseModle<T> {
    }

现在数据获取的方式已经有了,那怎么传递给p层呢?我们在之前也说过p层会持有m层的引用,所以我们可以在p层中调用层方法。

public class ContentPresenter implements ContentContract.Presenter {
    private ContentModel mModel;
    private ContentContract.View mView;
    //当初始化的时候  同时持有v层和m层引用
    public ContentPresenter(ContentContract.View m) {
        mView=m;
        mModel = new ContentModel();
    }
    //定义一个send方法,在该方法中调用m层的请求数据方法
     public void send(){
           mModel.sendHttpBannerData(new BaseModel.OnListener<String>() {
               @Override
               public void onSuccess(String s) {
                    //这里就可以直接使用v层方法处理数据,在v层中我们已经实想该函数
                    mView.getBanner(s);
               }
               @Override
               public void onFail(int code, String msg) {
               }
           });
    }
}

最后一步就是初始化p

public class MainActivty extends BaseQuickActivty implements ContentContract.View {
@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //初始化p
        ContentPresenter contentPresenter = new ContentPresenter(this);
        contentPresenter.send();//调用p层的send方法 开始请求数据
    }
    @Override
    public void getBanner(String  str) {
    }
}

这样我们就可以交互了,在接口中我们可以根据自己的需求增加方法,可以提供基类,这样没必要每次都重写方法,可以将一些通用的放在基类中。(可以先消化下,接下来我们做进一步的处理和避免内存泄漏问题)

我们分析下不足之处。

每一个presenter都需要每次重写相同代码,手动释放p等不足之处。所以我们先从presenter入手.


public abstract class BasePresenter<T> {
    //弱引用 
    private WeakReference<T> mWeakReference;
    private ReferenceQueue<T> mReferenceQueue = new ReferenceQueue<>();
    
    public void attachView(T t) {
        mWeakReference = new WeakReference<T>(t);
    }
    public T getView() {
        return mWeakReference.get();
    }
    
    public boolean isViewAttachecd() {
        return mWeakReference != null && mWeakReference.get() != null;
    }
    
    public void deleteAttach() {
        if (mWeakReference != null) {
            mWeakReference.clear();
            mWeakReference = null;
        }
    }
}

接着我们改进activity或者fragment的基类base

**
 * activity 基类
 * v 代表 view
 * t presenter
 */
public abstract class BaseQuickActivity<V, T extends BasePresenter<V>> extends AppCompatActivity {
    protected T mPresenter;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter = createPresenter();
        //这里做一下非空判断 有可能某些模块不需要mvp模式
        if (mPresenter != null) {
            mPresenter.attachView((V) this);
        }
    }
    protected abstract T createPresenter();
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mPresenter != null) {
            mPresenter.deleteAttach();
        }
    }
}
//fragment 一样的写法

这样我们基本上完善了mvp模式。mvp给我带来的好处很多,高度解耦,代码结构清晰(以前ac或者ft可以达到上千行代码,现在都交给了p和m),便于测试(不会)。但是同时也有缺点,第一感知就是类增多了。第二感知就是在交互时有些时候不方便。
上述结构体还是可以更加完善的,可以用eventbus或者rxjava用于沟通的桥梁和数据分发。

到此这篇关于Android MVP模式的写法浅析的文章就介绍到这了,更多相关Android MVP模式内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯