今天学习了一下官方的mvp封装,学习后,有了一些感想,这里和大家分享一下吧!
官方的mvp封装,思想·目的·目标都很明确,就是要逻辑思维简单,并且还要很好的控制内存的泄漏问题,简单点说:就是减少每个activity的绑定和解绑的代码操作,但是又需要很好的处理内存益出的问题!
既然已经知道了目的和目标,那我们需要做的就是思路和代码了!
首先考虑的是,Activity的抽取,为什么是Activity的抽取呢?因为当我们没有思路的时候,我们可以从结果入手,从我们的需求,从我们的目标来入手!我们的目的是为了减少每个activity的绑定和解绑的代码操作以及很好的处理内存益出,那么,我们就可以假设如果有多个activity的请求接口的话,我们就需要每个activity都要做一次和P层的解绑操作,因此,为了减少这样重复的事情多次操作,我们就可以进行抽取基类的操作,将所有绑定和解绑都放在一个基类里面进行运行。因此抽取activity基类是我们无论如何都跨不过去的梗!
说那么多可能有些小伙伴已经懵逼了,所以还是直接上代码吧!
Activity基类:
package bw.com.mvpfengzhuang.base;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import bw.com.mvpfengzhuang.R;
public class IActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_i);
}
}
可能已经有小伙伴看出来了,我只是新建了一个Activity而已!没错,我就是新建了一个activity,然后让其余的Activity(需要进行网络请求的Activity)都来继承这一个Activity就可以了!
接着就是这一个Activity的与P层的交互操作了,首先我们需要考虑的是如何来识别是哪一个Activity以及如何识别Presenter,于是乎,就有了泛型这样的怪胎出生!(泛型的概念:将类型参数化),然后我们就可以通过类型来进行指定对象,再通过对象调用方法(绑定。解绑),
于是这个IActivity就演变成了这样:
package bw.com.mvpfengzhuang.base;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import bw.com.mvpfengzhuang.R;
import bw.com.mvpfengzhuang.presenter.MyPresenter;
/**
*
* @param <V> v是activity
* @param <T> t是p层
*/
public abstract class BaseMVPActivity<V,T extends MyPresenter<V>> extends AppCompatActivity {
public T myPresenter;
//将子类共有方法抽成公有,,,因为每一个Activity都会需要new一个P层,所以将new的这个过程,抽成抽象方法才是最佳良策
public abstract T initPresenter();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_mvp);
myPresenter=initPresenter();
}
//在获取焦点是将当前对象与p层绑定
@Override
protected void onResume() {
super.onResume();
myPresenter.attch((V) this);
}
//在页面销毁时,调用p层方法,将view对象置空,方便垃圾回收
@Override
protected void onDestroy() {
super.onDestroy();
myPresenter.setonDestroy();
}
}
代码到这里,可能已经有机智的小伙伴们能够“窥一斑而知全豹”了。
接着就是P层的代码了:
package bw.com.mvpfengzhuang.presenter;
import android.util.Log;
import bw.com.mvpfengzhuang.interfaces.JieKou;
import bw.com.mvpfengzhuang.model.MyModel;
/**
*
* @param <V> v代表view视图
*
* p层依然是那么几步操作,
* 1.p与v的绑定
* 2.向model层传输url路径,并接收model层回调回来的数据
* 3.实现p与v的解绑
*/
//为p层指定泛型对象
public class MyPresenter<V> {
private final MyModel myModel;
V view;
public MyPresenter() {
myModel = new MyModel();
}
//将p层与v层绑定
public void attch(V view){
this.view=view;
}
//调用model层中的方法,传输url路径,接口回调数据
public void getPreContent(String url, final JieKou jieKou){
myModel.getModContent(url, new JieKou() {
@Override
public void chenggong(String json) {
jieKou.chenggong(json);
}
@Override
public void shibai(String ss) {
jieKou.shibai(ss);
}
});
}
//将p层与v层解绑,,同时将view置空
public void setonDestroy(){
Log.i("jiba","==="+this.view.toString());//检测Activity的销毁时的对象是否识别正确
this.view=null;
}
}
到这里,我们Activity的基类与presenter的交互就已经做的很完美了,下面就是进行网络请求的操作了,主要就是继承
BaseMVPActivity和传参数的过程了。
来,接着看代码:程序入口MainActivity:
package bw.com.mvpfengzhuang;
import android.os.Bundle;
import android.util.Log;
import bw.com.mvpfengzhuang.base.BaseMVPActivity;
import bw.com.mvpfengzhuang.interfaces.JieKou;
import bw.com.mvpfengzhuang.presenter.MyPresenter;
/**
* BaseMVPActivity<MainActivity,MyPresenter<MainActivity>>
*
* BaseMVPActivity<V,T extends MyPresenter<V>>
*
* V==MainActivity T==MyPresenter
*
*/
public class MainActivity extends BaseMVPActivity<MainActivity,MyPresenter<MainActivity>> {
String path="http://www.yulin520.com/a2a/impressApi/news/mergeList?pageSize=10&page=1";
//重写抽象方法,,,就是new P层对象的过程
@Override
public MyPresenter initPresenter() {
return new MyPresenter();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myPresenter.getPreContent(path, new JieKou() {
@Override
public void chenggong(String json) {
Log.i("jiba","==="+json);
}
@Override
public void shibai(String ss) {
Log.i("jiba","===="+ss);
}
});
}
}
最后就是model层的操作:
package bw.com.mvpfengzhuang.model;
import bw.com.mvpfengzhuang.interfaces.JieKou;
import bw.com.mvpfengzhuang.util.BaseServer;
import bw.com.mvpfengzhuang.util.RetrofitFacety;
/**
* Created by mypc on 2018/1/10.
*
* model层里,我做了retrofit+RxJava的封装处理,这里就不再展示代码了,向看代码可以到我的博客去看!
*
* 地址:http://blog.csdn.net/weixin_40430041/article/details/78988137
*/
public class MyModel {
public void getModContent(String url, final JieKou jieKou){
RetrofitFacety.get(null,url)
.subscribe(new BaseServer() {
@Override
public void onSuccess(String json) {
jieKou.chenggong(json);
}
@Override
public void onErroy(String ss) {
jieKou.shibai(ss);
}
});
}
}
效果: