RxJava+MVP

在公司项目中使用RxJava和MVP已经很久了,从一开始使用到不断完善这个结构,最近也看到很多QQ好友有类似这方面的问题,就想着把这个抽出来放到github上面,供大家参考。

先说说这个mvp把, mvp我自己的理解就是通过一个中间类,做一个View和Model之间的一个联系类,view和Model不再直接联系,达到程序解耦的目的。

MVP是一种设计模式,是一种思想,没有一个标准的实现过程,但是也要遵循一定的规则。MVP是基于接口的,我们都知道在程序中使用接口,在很多场景就是为了达到程序解耦。
接下来看一下MVP的一个模型图,来帮助我们更好地理解MVP模式。
这里写图片描述

使用MVP我自己感觉到最大的好处就是,程序变得简洁了很多,减轻了Activity的压力,把业务逻辑都放到presenter里面去做,也容易维护,但其实在MVP这种模式中,如果使用的不恰当的话,是非常容易导致内存泄漏的,因为presenter通常都需要持有Activity、Fragment的引用,来达到控制view的目的。

接下来我说说自己是如何设计这个MVP的结构的,当然也是参考了很多大神的源码,最后通过自己不断总结出来的一套适合自己的结构。

首先我们建立一个IBase类。这个是为我们的View层提供的一个接口,需要使用到Presenter的Activity都需要去实现这个IBase。里面就是声明几个基本的方法。

public interface IBase {

    //拿到ApplicationContext
    Context getMApplicationContext();

    //拿到当前类的Context
    Context getMContext();

    //判断有无网络
    boolean hasNet();

    //显示一个吐司框
    void showToast(String s);

    ...
}

这里我只列了几个基本的方法,首先 ApplicationContext我们在访问数据库,访问Sp等场景都会需要用到。Context就不用说了,判断有无网络,可以在发出网络请求的时候,先判断有无网络。

有了IBase我们可以开始写自己的BasePresenter

public abstract class BasePresenter<T> {
    String TAG = "BasePresenter";

    //view接口类型的弱引用
    protected Reference<T> mViewRef;

    private CompositeSubscription mCompositeSubscription;

    public void attachView(T view) {
        mViewRef = new WeakReference<T>(view);
    }

    protected T getView() {
        return mViewRef.get();
    }

    public boolean isViewAttached() {
        return mViewRef != null && mViewRef.get() != null;
    }

    public void dettachView() {
        if (mViewRef != null) {
            mViewRef.clear();
            mViewRef = null;
        }
    }

    //添加一个Subscription
    protected void addSubscription(Subscription s) {
        if (this.mCompositeSubscription == null) {
            this.mCompositeSubscription = new CompositeSubscription();
        }
        this.mCompositeSubscription.add(s);
    }

    //解除订阅
    public void unsubcrible() {
        if (this.mCompositeSubscription != null) {
            this.mCompositeSubscription.unsubscribe();
        }
    }
}

简单说一下思路,在attachView的时候把View注册到Presenter中(生成一个弱引用,主要是防止内存泄漏),然后通过getView拿到view的一个弱引用,声明方式均为接口。dettachView的时候释放弱引用,如果忘记释放了,或者在Activity finish的时候还不能结束网络请求,可以不调用dettachView,在网络请求结束后会自动释放。

addSubscription用于添加一个Subscription对象,unsubcrible解除所有订阅,在Activity finish的时候取消请求,可以先把请求的Subscription添加进来, finish的时候取消订阅。

接下来在我们的BaseActivity和BaseFragment中去实现这个IBase。

public abstract class BaseActivity<V,T extends BasePresenter<V>> extends AppCompatActivity implements IBase {
    protected T mPresenter;
    protected abstract T createPresenter();
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter = createPresenter();
    }

    //实现IBase中的接口
    ... 
}
public abstract class BaseFragment<V, T extends BasePresenter<V>> extends Fragment implements IBase {
    protected T mPresenter;
    protected abstract T createPresenter();

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter = createPresenter();

    //实现IBase中的接口
    ... 
}

基本框架搭建完成。
新建一个Activity或者Fragment、
比如,新建一个TestActivity,首先,我们要建一个ITest接口。

public interface ITest extends IBase {

    void showData(String data);
}

然后建一个TestPresenter, 严格来说是应该建一个ITestPresenter的,但是我把这个省了。

public class TestPresenter extends BasePresenter<ITest> {
    private ITest iview;

    public TestPresenter(ITest main) {
        this.attachView(main);
        iview = getView();
    }


    public void getData() {
        iview.showData("hello , i'm mvp");
    }
}

最后我们建一个TestActivity。

public class TestActivity extends BaseActivity<ITest, TestPresenter> implements ITest {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);


    }

    @Override
    protected TestPresenter createPresenter() {
        return new TestPresenter(this);
    }

    @Override
    public void showData(String data) {
        showToast(data);
    }
}

到这里一个MVP的框架搭建和使用基本完成了。看了这么多是不是感觉程序变得复杂了好多,不过一旦你真正理解了,并且应用到程序中,你会发现这种模式给你带来的巨大的好处。
以上代码均已上传到github,欢迎star。
https://github.com/sunflowerseat/MVPDemo

不过MVP每次要建这么多的类,的确是让人有点蛋疼,尤其是加上Dagger2 然后再加Presenter的接口的时候,随便一个activity就得新建五六个类。。。就算是复制粘贴也能把人累个半死。
作为程序员我们总能想到让自己偷懒的办法的, 真的每次建五六个类, 时间久了也是会疯的。

所幸的是最近不论是android还是web我们都能够是用模板工具,为我们生成许多重复的代码。

在android中我们可以使用FreeMarker语法按照自己的代码习惯编写一个MVPActivity和MVPFragment。

我也把模板Acitivity的代码发到了github上,供大家参考学习,共同进步。
https://github.com/sunflowerseat/MVPDemo/tree/master/MVPActivityTemplate/MVPActivity
https://github.com/sunflowerseat/MVPDemo/tree/master/MVPActivityTemplate/MVPActivity

下一篇博客会讲讲如何自定义一个Activity模板。

对本文内容有任何疑问欢迎加群讨论:283272067

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值