很多人不愿意写关于Android中MVP的文章,为啥呢,费时间,大家更喜欢用视频的方式,文章写起来太浪费时间了,所以咯,目前也只有我这样的离职人员有时间写了。话说回来,我们在工作中,你不可能对着一个视频教你写代码吧!小组长或者CTO在背后diss你,你不怕?所以来一下文章,边看边写,真香。还有人说这百度一大堆MVP的文章,为啥要看你的。这里,我希望你看完文章你就知道为什么,我现在写的才是你实际可以直接用的,百度很多都是知识教你认识,也有人写类似的文章,但我们每个人的都有些不一样,你可以集思广益,自己优化。先说下今天写哪些内容,首先,我们还是简单的比较下MVC,MVVM,MVP,然后我们就开始撸代码,最后我们就讲一下MVP优化。
MVC有两个很明显的问题:
1.m层和v层直接打交道,导致这两层耦合度高
2.因为所有逻辑都写在c层,导致c层特别臃肿
我相信很多Android的开发工程师都还在用MVC模式,我自己的同学,包括前同事等,目前都在用,问他们为啥,回答都是简单,项目周期紧,没时间,MVP接口多,写起来麻烦,所以直接怼代码。(如果是做服务端的人肯定奇怪为啥Android居然可以用MVC写的下去),实际上MVP众多的缺点都是可以用代码解决的。
MVP:
p层代替了了c层,v层和m层的交互被p层隔断,从理论上去除了v和m层的耦合。
但是造成p层比原来的c层更加臃肿,为了缓解这种臃肿,MVVM出现了
MVVM:
简单的来说MVVM其实就是MVP中把P层削弱为VM层,部分简单的逻辑职责分给了View层。但是有一个很大的问题,也是至今这个模式比MVP模式用的少太多的原因,那就是占用内存,比方说,如果你用MVP开发的app只是占用1G的内存的话,那MVVM差不多就要占用2.5G。至于为什么,那一讲又是一内容,本来今天讲的就会很多。所以有兴趣的同学自己去学习。
好了,现在我们来撸项目,用项目说话,更直观,我们首先来百度一大堆的那个教程先写一遍,然后我们来优化。
先来看看大部分人写法看下图:
然后我们看下跑出来效果:
然后我们用内存分析工具,我们拍一张内存照片,然后在GC一下,我们看看会发生什么:
如果看不懂这个图的,可以自己去学习一下。看出了什么没有,
两张图对比,本来GC完这个activity会回收的,然而现实并没有。现在我们来改代码,改成MVP的模式,百度上已经基础的教我们怎么写了,我们直接写,我以下截图都是类跟接口,然后上截图。(接口跟类起名比较随意,只是例子,实际中都有规范)
这个就是View层,只要是做回调把数据回调给activity
model层接口,很多人直接写void loadDate(ListModelBean listModelBean);这个是不对的,因为我们的数据大多数是从服务器来的,所以只要加载速度过长那就会直接卡在这里,所以我们创建内部接口进行回调
model类,所有的数据逻辑都是在这个地方处理,继承ITaskModel接口把数据传递进去,此时我们完成了M层和V层,现在就差P层,这个时候我们可以一个形象的比喻,P是身体,M层跟V层是左右手。是不是很像。下面我们来创建P层
P 层第一我们肯定先写出两个接口(左右手)ITaskview,ITaskModel,然后构造函数,然后初始化,有没有发现我们的初始化跟百度的很多不一样,这里有人问为什么要用泛型,这里好处很多啊!大家可以自己体会下,我就不讲好处,思考使我们必须具备的能力。现在直接在P层执行UI逻辑,并且通过view层回调给activity
activity里面代码是不是少很多,像加载数据之类的跟activity全部给了model。这是基本的MVP,大家执行下效果。现在我们并不是大功告成,大家想想,如果数据不能及时回收怎么办?内存泄漏怎么办?还有我们的MVP会创建那么多接口,看着就麻烦怎么办?这个是可以通过代码解决的,这也是研究一点跟只会基础掌握的区别。下面我们开始优化代码,我们目光转移到P层,然后我们把数据弱引用来解决内存泄漏问题。看下图:
看到改了什么没有,我们注销ITaskview,然后用弱引用的方式,这样内存在不足的时候GC就回收。运行效果看看,我们主要看内存,这个我想大家会在控制台看变化。当然我们这个还没做完,而且也不是最好的办法,这个时候我们咋办呢?很简单,绑定跟解绑,有没有很熟悉。继续P层:
我们把构造函数里面做的事情放在绑定和解绑里面。
调用绑定和解绑,这样只要销毁activity,GC就会回收。现在我们MVP算是完成了,但是我们P层会特别多,我们怎么优化?所以我们我们就需要各种创建基类。下面我们来操作:
把绑定解绑直接放在基类里面
继承基类,并去掉公共方法。
继承BaseActivity然后去除那些绑定解绑之类的公共方法。现在我们基本上完善了MVP的优化,大家可以有一个小测试,那就是我们直接修改xml里面的View(RecyclerView或者listView)更换成GridView,看看是不是有一个小惊喜。现在我们优化了activity的内存泄露。讲了这么多,真的特别累人,不过现在还有问题,我们如何优化model层呢?model是比较麻烦的,先看看实际开发中我们遇到的基本是这几个问题:
无法对所有Model统一管理。
每个Model对外提供的获取数据方法不一样,上层请求数据没有规范。
代码冗余高,网络数据请求除URL和参数外其他大概都一样的。
对已存在的Model管理困难,不能直观的统计已存在的Model。
model层我们优化就一句话,单独封装,集中管理或者我们弄一个事件总线RXBus(推荐)来调度。是不是一说就很简单了?一看时间又花了三小时了,整理这篇文章已经超过四个小时了,下次再说如何优化model层。最后心疼一下程序员,唉~分享使我快乐,MVP我只是在这个地方提供这么一个思路,优化的路还很长,里面细节问题,欢迎自己思考,现在写到这样吧!赠人玫瑰,手有余香。哈哈!一个爱程序的加班狗。