Android开发:浅谈MVP模式应用与内存泄漏问题解决
最近博主开始在项目中实践mvp模式,却意外发现内存泄漏比较严重,但却很少人谈到这个问题,促使了本文的发布,本文假设读者已了解mvp架构。
mvp简介
m-modle,数据,逻辑操作层,数据获取,数据持久化保存。比如网络操作,数据库操作
v-view,界面展示层,android中的具体体现为activity,fragment
p-presenter,中介者,连接modle,view层,同时持有modle引用和view接口引用
示例代码
modle层操作
public class testmodle implements imodle{ private callbacklistener callback; public testmodle(callbacklistener callback) { this.callback = callback; } public interface callbacklistener { void ongetdata(string data); } public void getdata() { new thread() { public void run() { callback.ongetdata("返回的数据"); } }.start(); } }
view层
// 抽象的view层 public interface testviewinterf extends iview { void ongetdata(string data); } // 具体的view层 public class mainactivity extends activity implements testviewinterf{ private testpresenter mtestpresenter; @override public void oncreate(@nullable bundle savedinstancestate) { super.oncreate(savedinstancestate); // view层将获取数据的任务委派给中介者presenter,并传入自身实例对象,实现testviewinterf接口 mtestpresenter = new testpresenter(this); mtestpresenter.getdata(); } @override public void ongetdata(string data) { // view层只做数据展示 showtoast(data); } private void showtoast(string toast) { toast.maketext(this, toast, toast.length_long).show(); } }
presenter中介者
public class testpresenter implements ipresenter{ imodle modle; iview view; public testpresenter(iview view) { this.view = view; } public void getdata() { // 获取数据的操作实际在modle层执行 modle = new testmodle(new callbacklistener() { public void ongetdata(string data) { if (view != null) { view.ongetdata(data); } } }); modle.getdata(); } }
根据oop思想,java应面向接口编程,这样才能给符合ocp原则。上述示例代码省略了更加抽象的接口imodle,iview,ipresenter,并且实际mvp实践中通常会引入泛型使其更具扩展性。
google已提供了相关示例代码,并在mvp中增加了一个约束者:contract,它的作用是定义各个模块的mvp接口。
google mvp sample code:https://github.com/googlesamples/android-architecture
内存泄露问题
由上可见,presenter中持有view接口对象,这个接口对象实际为mainactivity.this,modle中也同时拥有presenter对象实例,当mainactivity要销毁时,presenter中有modle在获取数据,那么问题来了,这个activity还能正常销毁吗?
答案是不能!
当modle在获取数据时,不做处理,它就一直持有presenter对象,而presenter对象又持有activity对象,这条gc链不剪断,activity就无法被完整回收。
换句话说:presenter不销毁,activity就无法正常被回收。
解决mvp的内存泄露
presenter在activity的ondestroy方法回调时执行资源释放操作,或者在presenter引用view对象时使用更加容易回收的软引用,弱应用。
比如示例代码:
activity
@override public void ondestroy() { super.ondestroy(); mpresenter.destroy(); }
presenter
public void destroy() { view = null; if(modle != null) { modle.cancletasks(); } }
modle
public void cancletasks() { // todo 终止线程池threadpool.shutdown(),asynctask.cancle(),或者调用框架的取消任务api }
个人总结
因为面向mvp接口编程,可适应需求变更,所以mvp适用于比较大的项目;因为其简化了activity和fragmnt的职责,可大大减少view层的代码量,比起mvc中activity,fragment动不动上千行的代码量,简直优雅!
做完以上操作,由于mvp引起的内存泄露就差不多解决了,以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: java实现的满天星效果实例