MVP
来源:互联网 发布:公务员网络课程 编辑:程序博客网 时间:2024/06/01 08:04
MVP
关于MVP模式的总结
- MVP意义
- 简单实现
- 隐藏风险
- 优化
MVP意义
为了解耦合,将页面刷新逻辑和数据加载逻辑区分开来。M->model,进行数据加载;V->view(Activity,Fragment),进行页面业务控制,P->presenter,将M和V结合起来。
V 相当于一台笔记本,如果把音箱、打印机等设备都组装到笔记本上,则显得笔记本比较复杂,体积变大。如果在笔记本上开一个接口,其他设备通过相应数据线(P)连接,那个对于笔记本来说,只要选择要连接的数据线,对于数据线来说,只要选择要连接的设备,对于设备来说,只要做自己的操作,把 数据给数据线,,通过这这种方式,使业务模块化,也更易扩展。MVP 就是这种思想。
MVP简单实现
写View接口
写一个view 接口,包含一个方法,主要用于展示数据,同时写Activity实现此接口,重写showView 方法,在此方法中进行数据刷新加载
public interface BaseMvpView { public void showView(List<String> list);}
写model
model,进行数据加载,包含两个部分,加载数据的方法,和加载完成后数据的回调;
public interface BaseMvpMode { public void getData(GetDataCompleteInterface getDataCompleteInterface); public interface GetDataCompleteInterface{ public void complete(List<String> list); }}
写presenter
presenter,每一个Activity 都应有一个对应的presenter,用于进行数据操作模块的选择和数据的回调展示(连接V和M),包含一个执行方法,调用此方法开始加载数据,重写model的回调接口,实现数据回调,调用View 的方法,实现展示
public class MvpPresenter { private MvpModel mvpModel; private MvpView mvpView; public MvpPresenter(MvpView mvpView){ this.mvpView = mvpView; mvpModel = new MvpModel(); } public void LoadingData(){ mvpModel.getData(new BaseMvpMode.GetDataCompleteInterface() { @Override public void complete(List<String> list) { mvpView.showView(list); } }); }}
隐藏风险
空指针
由于页面逻辑和数据加载逻辑分开,当数据加载完成时,如果View已销毁,那么会造成空指针的现象(不该销毁时销毁了)
内存泄露
因为P 中有V 的引用,当V要销毁时,由于未完成加载,P中有V 的引用导致v不能销毁,造成内存泄露(该销毁时没销毁)
解决方法
造成上述两种问题的原因,都是因为P和V 的引用的原因,如果在P 中保存为V 的弱引用,那么问题就可以有效避免,因此要对上述MVP逻辑进行优化。
优化
主要思想是让P 中保存V 的弱引用,由于P 和V 的个数、不定,为了避免重复代码操作,分别抽象P 和 V 的基类,在基类中完成引用的绑定。
- P 基类
1 得到 V 绑定为弱引用
2 提供 V 弱引用
P主要保存引用关系,在基类中将V和P 绑定为弱引用,对于每个继承此基类的P,都能有此操作,避免重复。采用泛型V ,在生成p 时 传过来的V,为V 的实现类,可以正常进行刷新。基类主要做两个操作,绑定引用,提供引用(为保证提供的引用就是当前的V,所以设置V 采用虚方法在子类实现,保证引用为实现类)
public abstract class BaseMvpPresenter <V extends BaseMvpView> { private WeakReference<V> weakReference; public void attachView(V baseMvpView){ weakReference = new WeakReference(baseMvpView); } public void dettachView(){ if(weakReference!=null){ weakReference.clear(); weakReference = null; } } public V getWeakPerence(){ return weakReference.get(); }}
- V基类
1 实例化P
2 绑定P 和 V
V基类主要进行 P和V的绑定,需要P实例,由于要绑定的P 实例 不定,因此采用泛型T extents P基类, 又P基类有泛型,需要一个V,因此V基类也要声明出泛型V,传给P基类。对于实例P,因为每个实现类不同,因此P 的 构建应放在实现类中,抽象方法 setBaseMvpPresenter();
public abstract class BaseMvpActivity <V extends BaseMvpView,T extends BaseMvpPresenter<V>>extends AppCompatActivity { protected T baseMvpPresenter ; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); baseMvpPresenter =setBaseMvpPresenter(); baseMvpPresenter.attachView((V)this); } @Override protected void onDestroy() { super.onDestroy(); baseMvpPresenter.dettachView(); } public abstract T setBaseMvpPresenter();}
V实现类
继承V基类,主要提供V 基类需要的泛型(V ,T),实现虚方法,创建P实例
public class ActivityMvp2 extends BaseMvpActivity <BaseMvpView,MainMvpPresenter>implements BaseMvpView { private ListView listView; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mvp2); initView(); initData(); } @Override public MainMvpPresenter setBaseMvpPresenter() { return new MainMvpPresenter(); } private void initData() { baseMvpPresenter.setModel().loadingData(); } private void initView() { listView = (ListView) findViewById(R.id.listview); } @Override public void showView(List<String> list) { ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,list); listView.setAdapter(adapter); }}
P实现类
继承P基类,声明P基类需要的泛型V,同时调用基类中保存的 弱引用(getWeakPerence),实现V 的刷新
public class MainMvpPresenter extends BaseMvpPresenter<BaseMvpView>{ BaseMvpMode baseMvpMode; public MainMvpPresenter(){ } public MainMvpPresenter setModel(){ baseMvpMode = new MvpModel(); return this; } public void loadingData(){ baseMvpMode.loadingData(new BaseMvpMode.LoadCompleteInterface() { @Override public void loadComplete(List<String> listData) { getWeakPerence().showView(listData); } }); }}
小结
基类的编写和泛型的使用,对于P基类 ,因为不知道要绑定的
V引用是什么,因此 使用泛型V 继承基类 V,,
对于 V基类,因为不知道P类型,因此使用泛型P继承基类P,同时要实例化P,但P不定,因此写虚方法,子类实现。
- MVP
- MVP
- MVP
- MVP
- MVP
- MVP
- MVP
- MVP
- mvp
- MVP
- MVP
- mvp
- MVP
- MVP
- MVP
- MVP
- MVP
- MVP
- 单向链表
- java面试宝典--集合类
- 阿里云大数据助理工程师认证(ACA)
- 购物车子条目
- 增删改查排序 Month练习1
- MVP
- LUA 排序算法和性能分析[2]:冒泡排序算法
- 前后端分离开发背景下,前端如何使用nginx代理转发ajax跨域访问后台服务?
- HTTP Status 500
- 漏洞真实影响分析,终结网络安全的“狼来了”困境
- Activiti实现流程定义的控制与修改
- 如何判断一个String字符串不为空
- 关于二叉树创建时遇到的问题的解决
- 初学者---Android 接口回调