这几天都在研究如何搭建一个实用稳固的MVP架构作为快速开发的基底。 也纠结了很久Presenter层该如何复用,在网上查阅了很多资料之后仍然没能找到一个适用的办法,有的写法单纯是为了presenter的复用而写,却给其他模块增负担;有的实现的手法过于僵硬,不符合写代码的原则。 在看完各种奇奇怪怪的实现思路之后,自己内心也有了一个实现presenter复用的一套方法,不过还不知道可不可行,到时撸完了可行再贴出来。

走过路过点歌Start O(∩_∩)O Github项目地址

这篇文章先撸一遍MVP的基本框架搭建,看完这篇文章你能学会:

  • 一个还不错的Mvp框架结构是怎样的
  • Mvp框架如何避免内存泄漏
  • Presenter层如何复用?这一个以后确定可行再撸

顺着我的思路来一遍,先构造基类: 首相是对View层的基类下手, IBaseView

package com.example.administrator.mvpframedemo.base;public interface IBaseView {}
复制代码

实不相瞒,这个我一个方法都没定义。看到网上有很多人会把showToast()等这样的方法定义在这里喔我就不同意了,因为这些太重复固定的我觉得放在基类让每个子类去实现实在麻烦,所以我怎么做呢?我把showToast这样重复的实现放在BaseActivity;下面一起看一下 BaseActivity

public abstract class BaseActivity extends AppCompatActivity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {initBeforeCreate();super.onCreate(savedInstanceState);setContentView(getLayoutId());init(savedInstanceState);initData();initView();logic();}protected abstract void initBeforeCreate();protected abstract int getLayoutId();protected abstract void init(Bundle savedInstanceState);protected abstract void initData();protected abstract void initView();protected abstract void logic();protected void showToast (String toastStr) {Toast.makeText(this, toastStr, Toast.LENGTH_SHORT).show();};
}
复制代码

这是在没啥好说,这里释放了更BaseActivity有关的,而不是跟Mvp有关的。至于你了解的BaseActivity中要处理presenter绑定,解绑这样的操作我会另外建一个BaseMvpActivity来做专门针对Mvp的处理的。保持这样结构的整洁还是感觉神清气爽的;当然BaseMvpActivity还是要继承BaseActivity的;万一哪天天收的说这个模块我要用MVC之类的时候也好处理一点。 接下来就是 BasePresenter

public class BasePresenter<V extends IBaseView>  {private WeakReference<V> mViewRef;public V mView;public void attachView(V view) {mViewRef = new WeakReference<V>(view);mView = mViewRef.get();}public void detachView() {mViewRef.clear();mView = null;}
}
复制代码

这里定义了attachView()以及detachView()两个接口;这是为啥?还有为什么要有mViewRef? 首先说为什么要attachView()?这个其实只要你敲过一些简单的mvp的代码就会知道,每一次都要写这样的代码:

MainActivity{// 这一句代码做了两个事情,①View层创建自己适合的Presenter,②然后把自己传给Presenter完成两者的绑定Presenter presenter = new Presenter(MainActivity.this);
}
复制代码

那么attachView()就是完成②的事情,至于①是留给View层自己去实现的,后面会说到。 所以attachView()诞生的原因就了解了,那么detachView()设计的原因呢? detachView()还有mViewRef的出现都是为了解决内存泄漏而存在的。那么是怎么解决内存泄漏的存在呢? 当一个Activity在显示的时候退出了,GC在感觉内存紧张的时候会想把这个Activity给回收掉,但是此时presenter对象是持有Activity对象的,所以GC就没办法回收了,这样就存在泄漏的隐患了。这种持有activity对象而引起内存泄漏是非常常见的原因。 所以我们使用deacttach()以及mViewRef(弱引用)来解除两者的绑定,让GC随心所欲。那什么时候解绑呢?在Activity的onDestroy()生命周期的时候合适。 那么接下来就是: BaseMvpActivity

public abstract class BaseMvpActivity<T extends BasePresenter> extends BaseActivity implements IBaseView {protected T mPresenter;@Overrideprotected void init(Bundle savedInstanceState) {mPresenter = bindPresenter();mPresenter.attachView(this);}protected abstract T bindPresenter();@Overrideprotected void onDestroy() {super.onDestroy();mPresenter.detachView();}
}
复制代码

这个BaseMvpActivity里面做了针对Mvp的事情,包括定义bindPresenter()创建自己合适的presenter,然后执行presenter.attachView(this),将两者进行绑定;最后在onDestroy()方法中接触两者的绑定。

--------------------------------------人工分割线---------------------------------------------------------------------- 到这里,关于Mvp的基类设计好像就差不多了。 然后来模拟看看实际上要进行的业务: 登录页面要请求登录 第一步:在constract(合约层,维护P层与V层的关系) 建立一个LoginConstract

public interface LoginContract {abstract class LoginPresenter extends BasePresenter<LoginView>{public abstract void login(String name, String password);}interface LoginView extends IBaseView {void showTips(String str);}
}
复制代码

在合约里面定义LoginPresenter以及LoginView的接口;实现交给其他地方。 在这里开发者就要明白登录的逻辑,例如:首先View利用presetner发起登录(login)请求,请求完成之后View要给用户显示结果(showTips);所以在上面定义的接口也是这么来的。 实现: LoginPresenter:

public  class LoginPresenter extends LoginContract.LoginPresenter {ILoginModel loginModel;@Overridepublic void login(String name, String password) {loginModel = new LoginModel();loginModel.login(name, password, new LoginCallBack());}private class LoginCallBack implements ICallBack<LoginDomain, Exception> {@Overridepublic void onSuccess(LoginDomain result) {mView.showTips("登录成功");}@Overridepublic void onFail(Exception error) {mView.showTips("登录失败");}}
}
复制代码

简简单单,login()方法需要用到model层去帮忙获取数据。所以实例化合适的model,然后调用它取数据的接口。 我一般会把model层分为interface以及impl两层,一个定义接口,一个实现。 不过关于Presenter与Model层的交互问题需要说明一下:因为Model层取数据大多未异步操作,所以通常使用接口回调的方式。所以在调用Model的login()取数据的时候传递一个回调对象来实现异步。 LoginModel:

public class LoginModel implements ILoginModel {@Overridepublic void login(String username, String password, ICallBack<LoginDomain, Exception> callBack) {// 模拟一部网络获取try {Thread.sleep(2000);callBack.onSuccess(new LoginDomain("周润发","123"));} catch (InterruptedException e) {e.printStackTrace();callBack.onFail(new Exception());}}
}
复制代码

到了这里其实只有一些细节的问题了,关于presenter与model层的ICallBack回调如何统一规范等等都是小事。 最重要的是presenter如何复用?敬请期待我之后的博文。

最后是我的项目的目录结构:

Android从零开始(第三篇)MVP架构搭建相关推荐

  1. <Android开发> Android vold - 第三篇 vold 的NetLinkManager类简介

    本系列主要介绍 Android vold,分为以下篇章 <Android开发> Android vold - 第一篇 vold前言简介 <Android开发> Android ...

  2. android 服务架构,Android MVP架构搭建

    目录 引言 为什么用MVP架构 MVP理论知识 乞丐版MVP架构模式的代码实现 MVP中的代码复用场景 平民版MVP架构 - base层顶级父类 Fragment怎么办 时尚版MVP架构 - Mode ...

  3. android音乐播放器(mvp架构)

    1.最终效果 功能:播放.暂停.停止.可拖动进度条等. 个人建议有一定基础看本篇博客. 为了条理清晰易于学习,代码只针对最主要的功能,可自行进行扩展. 没有对代码进行过多的阐述,可以先将功能实现之后, ...

  4. Android框架式编程之MVP架构

    MVP是Google官方发布的Android开发相关的架构知识.本文要讲解的是一种最基本的MVP的实现方式,它使用手动的依赖注入来提供具有本地和远程数据源的存储库.异步任务处理回调. 基本的MVP示例 ...

  5. 简析Android中的MVC、MVP架构

    MVC MVC是指Modle,View和Controller,将界面,业务逻辑和控制器分开,是一种低耦合的设计方式,适用于简单应用开发.举个简单的例子.android中的各种控件,即为View.例如, ...

  6. Android JNI 第三篇 Java参数类型与本地参数类型对照

    转载请标明出处: http://blog.csdn.net/michael1112/article/details/56665383 江东橘子的博客 这一篇从基础上了解一些Java参数类型与本地参数类 ...

  7. 谈谈 Android MVP 架构 | 掘金技术征文

    前言:本文所写的是博主的个人见解,如有错误或者不恰当之处,欢迎私信博主,加以改正!原文链接,demo链接 MVP 架构简介 说起 MVP 架构,相信很多朋友都看过,网上也有很多这方面的资料.博主使用 ...

  8. Android官方MVP架构详解

    综述 对于MVP (Model View Presenter)架构是从著名的MVC(Model View Controller)架构演变而来的.而对于Android应用的开发中本身可视为一种MVC架构 ...

  9. <Android开发> Android vold - 第四篇 vold 的NetlinkHandler类简介

    本系列主要介绍 Android vold,分为以下篇章 <Android开发> Android vold - 第一篇 vold前言简介 <Android开发> Android ...

最新文章

  1. 使用yum更新时不升级Linux内核的方法
  2. 练习_用if语句替换三元运算符
  3. c语言 常量字符串数组,C语言常量以及字符串数组
  4. [渝粤教育] 重庆工业职业技术学院 汽车安全与舒适系统维修 参考 资料
  5. python bokeh_提升视觉效果:使用Python和Bokeh制作交互式地图
  6. android string 去掉斜杠,Android – PATH中的改装和斜杠字符
  7. vue学习笔记(五):对于vuex的理解 + 简单实例
  8. Part Six 地理定位API
  9. 别再用 Visio 了!试试这个比它快 10 倍的画图工具不香吗?
  10. 使用JAVA的keytool生成jks证书,通过jks证书生成pfx证书,tomcat配置https
  11. android游戏开发学习笔记一(学习书籍 Android游戏编程之从零开始)
  12. win10状态栏点击没反应解决办法
  13. 优盘在计算机上无法显示,U盘在电脑上不显示的原因
  14. FC游戏 《三国志2-霸王的大陆》攻略
  15. Writeup-GKCTF-Misc题:Harley Quinn
  16. JAVA读取Excel表格,建数据库建表,并生成java实体实例
  17. 邮箱大师支持html,网易邮箱大师pc版
  18. 【数据库的备份与还原】
  19. Ubuntu 16.04通过Trickle限制某个软件的下载/上传速度
  20. Java语言程序设计与数据结构(基础篇)梁勇第九章 *9.3

热门文章

  1. python gui label_更新tkinter Label以在pythongui上显示一个文本文件,每次一行
  2. php mysql增删改查实例_php连接数据库实现用户数据的增删改查实例
  3. 连续低频脑电图解码手臂运动,实现机械手臂的闭环自然控制
  4. 计算机软件和硬件比较,软件与硬件RAID优劣之比较
  5. 用摩斯电码通关《黑暗之魂3》!up主自制奇葩手柄,连育碧都找上门合作
  6. 北航成AAAI 2021最大赢家,两篇一作斩获最佳论文、提名奖,研究皆与Transformer相关...
  7. 波士顿动力机器狗半夜遛弯儿惊呆路人,还配合拍照,网友:想到了《黑镜》...
  8. 国产岚图入局高端智能电动车,对标特斯拉,放话一年内量产
  9. 为什么老编辑器Vim这么难用,却很受欢迎?
  10. 全球首个AI驾校教练+驾照考官已上岗,装手机里就能用,再也不怕挨教练骂了...