Android上的MVP有两种思路实现:
一种是将Activity、Fragment等作为view,抽象出来一个Presenter来实现;
一种是将Activity、Fragment等作为Presenter,抽象出来一个View来实现。
两种思路各有利弊。
第一种思路是大家使用最多的,比较好理解,比较符合原MVP的思想,Presenter可以复用,但有个最大的缺点是Presenter不能被系统托管声明周期,Presenter需要持有Activity、Fragment等View的引用,不加处理或处理不当很容易引起内存泄漏。
第二种思路最大的优势就是Presenter是以Activity、Fragment为基础,这样它的生命周期被系统托管,不用做过多的干涉,而View可以被复用,而缺点是Presenter是不能被重用,比如:原Presenter是一个Activity,而要调整为Fragment时需要重写,而如果是Dialog、Adapter等需要根据其特性重写,还有就是Presenter一个自身就可操作界面的,在编写代码中很有可能会“一不小心”就写了操作界面的代码。
这两种思路实现MVP没有所谓的完全正确或错误,只是看个人或团队喜好和协定而已,使用MVP最主要是使用它的思想,代码分层,功能和界面分离,是修改和维护更加容易。
是不是项目上所有的界面部分都要使用MVP的思想实现?
个人感觉是视情况而定,有些太复杂的或太简单的,可以不用MVP的思想实现。比如:
如果一个Activity功能非常简单,这个Activity被其它地方调用,只展示传递过来的数据,那这个Activity完全可以不需要使用MVP,因为这样的Activity只需要寥寥几行代码即可实现,如果使用MVP的思想,那还得抽象出来几个接口类,有几个 对应的实现类,反而复杂得不偿失。太复杂的界面,暂时没有想好怎么举例。
关于MVP还有接口粒度(尤其是指更新界面的接口)划分的问题,这个问题个人感觉无法给出统一的“标准”定义,这个应该也是视情况而定。比如:一个登陆验证界面功能,更新界面的接口提供哪些?界面提供的接口是仅仅只有onSuccess()、onFail()? 还是onSuccess()、onFailForVerifyFail()、onFailForNetError()、onFailForUserNameError()等等?个人感觉,这个是在团队内部协商的,只要大家理解的一致,并且根据项目的特点有利于今后的扩展、修改和维护即可。
==========================================================================================
关于第一种思路:
将Activity、Fragment等作为view,抽象出来一个Presenter来实现;
它最大的缺点是处理不好View的生命周期时容易引起内存。
如果在Presenter和Module中使用的RxJava方式,那么可以在View中引入RxLifecycle来解决。代码如下:
MainModule mainModule = new MainModule();
mainModule.getData("abc")
.observeOn(AndroidSchedulers.mainThread())
.map(new Function<String, Object>() {
public Object apply(String s) throws Exception {
Log.v("testMvp", "apply s = " + s);
view.showMsg(s);
return s;
}
})
// compose是用于感知view的生命周期,其中view是集成RxActivity或RxFragement
.compose(((LifecycleProvider)view).bindToLifecycle())
// doOnTerminate 用于感知事件流的结束,当事件流结束时调到此处
.doOnTerminate(new Action() {
public void run() throws Exception {
Log.v("testMvp", "doOnTerminate...");
//如果调到此处了,并且view不为null,而且view是已经onDestory了,则置空null,否则会引起内存泄漏
if( view != null && ((Activity)view).isDestroyed()){
view = null;
Log.v("testMvp", "view == null");
}
}
})
.subscribe();
其中使用RxLifecycle在build.gradle中:
compile 'com.trello.rxlifecycle2:rxlifecycle:2.2.1'
compile 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.1'
compile 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.1'
参看: