基于MVP模式,设计自己的RxJava+Retrofit2+Okhttp3+Rxlifecycle开发框架

本文介绍了如何基于MVP模式设计一个完整的Android开发框架,结合RxJava、Retrofit2、Okhttp3和Rxlifecycle,涵盖网络请求、文件上传下载、无网络缓存等功能。详细讲解了框架各部分的实现,包括BaseAct、BasePresenter、BaseModule等基类的封装,以及网络层的RxRequestCallback、HttpClient、AppService的使用。此外,还提供了源码链接供读者参考学习。
摘要由CSDN通过智能技术生成

在开发阶段,如果有一个好的开发框架,不仅能提高开发效率,更能减少后期维护的时间。结合自己的实际,封装了一套MVP+RxJava+Retrofit2+Okhttp3+Rxlifecycle+Butterknife的开发框架。架构层:V层只负责视图的操作,P层只负责数据的交互,M层负责逻辑的处理,应该属于完整意义上的MVP代码结构模式。网络层包括:普通的get/post请求,文件上传、文件带进度下载,无网络缓存策略,请求带加载的dialog等。

先直接上代码链接:

GitHub: https://github.com/634930172/JohnDevFrame

点击打开链接

CSDN: https://download.csdn.net/download/a634930172a/10489294

点击打开链接

 

本项添加的依赖如下:

//Network
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
//RxJava
implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'io.reactivex:rxjava:1.3.0'
//RxLifecycle
implementation 'com.trello:rxlifecycle:0.3.0'
implementation 'com.trello:rxlifecycle-components:0.3.0'
//ButterKnife
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor'com.jakewharton:butterknife-compiler:8.8.1'


MVP模式设计

MVP模式大家应该都有了解过,V层想要得到某个数据然后做视图操作,需通过P层向M层发送请求,M层处理后的结果回调给P层,P层再回调给V层,期间的传递过程都是通过接口访问的。


本项目的结构如下所示:


 

下面看看封装MVP的思路吧。

首先是对Base各个基类的封装。BaseAct如下所示:

public abstract class BaseAct<V,extends BasePresenter<V>> extends RxAppCompatActivity  {
    
public Activity mActivity;
    public 
mPresenter;


    
@Override
    
public void setContentView(@LayoutRes int layoutResID) {
        
super.setContentView(layoutResID);
        
ButterKnife.bind(this);
        
mActivity this;
    
}

    
@Override
    
public void setContentView(View view) {
        
super.setContentView(view);
        
ButterKnife.bind(this);
        
mActivity this;
    
}

    
@Override
    
protected void onCreate(Bundle savedInstanceState) {
        
super.onCreate(savedInstanceState);
        
mPresenter = createPresenter();
        
mPresenter.attachView((Vthis);
        
setContentView(getLayoutId());
        
initView();
        
initData();
        
initEvent();

    
}


    
protected abstract int getLayoutId();

    protected abstract 
createPresenter();


    
/**
     * 
初始化View
     */
    
protected void initView() {
    }

    
/**
     * 
初始化数据
     
*/
    
protected void initData() {
    }

    
/**
     * 
初始化事件
     
*/
    
protected void initEvent() {
    }

    
@Override
    
protected void onDestroy() {
        
if (mPresenter != null) {
           
mPresenter.detachView();
        
}
        
super.onDestroy();

    
}


}

其中V为View的泛型,P为Presenter的泛型,RxAppCompatActivity是Rxlifecycle包下的,如下所示。该类继承了AppCompatActivity,增加了bindUntilEvent()和bindtoLifecycle()等方法,配合网络请求绑定生命周期的方法,可以避免内存泄漏。mPresenter通过调用attachView()和detachView()实现手动绑定和解绑,也起到了防止内存泄漏的作用。

public class RxAppCompatActivity extends AppCompatActivity implements ActivityLifecycleProvider {

    private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();

    @Override
    public final Observable<ActivityEvent> lifecycle() {
        return lifecycleSubject.asObservable();
    }

    @Override
    public final <T> Observable.Transformer<T, T> bindUntilEvent(ActivityEvent event) {
        return RxLifecycle.bindUntilActivityEvent(lifecycleSubject, event);
    }

    @Override
    public final <T> Observable.Transformer<T, T> bindToLifecycle() {
        return RxLifecycle.bindActivity(lifecycleSubject);
    } 

BasePresenter如下所示:

public abstract class BasePresenter<V> implements Presenter<V> {

    protected WeakReference<V> mMvpView;

    @Override
    public void attachView(V mvpView) {
        this.mMvpView = new WeakReference<>(mvpView);
    }


    protected V getView() {
        return mMvpView.get();
    }


    @Override
    public void detachView() {
        if (mMvpView != null) {
            mMvpView.clear();
            mMvpView = null;
        }
    }

BasePresenter将BaseAct绑定的View视图包装成弱引用,防止了内存泄漏(三重保障,稳稳的不泄漏)。Presenter是一个提供方法的接口,如下:

public interface Presenter<V> {

    void attachView(V view);

    void detachView();

}

BaseModule如下所示:

public class BaseModule {

    protected BaseAct mActivity;
    protected BaseFrag mFragment;

    public BaseModule(BaseAct act){
        this.mActivity=act;
    }

    public BaseModule(BaseFrag frag){
        this.mFragment=frag;
    }

    protected  <T> void addActSubscribe(Observable<T> observable,Subscriber<T> subscriber ) {
        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(mActivity.<T>bindUntilEvent(ActivityEvent.DESTROY))//绑定生命周期,防止内存泄露
                .subscribe(subscriber);
    }

    protected  <T> void addFragSubscribe(Observable<T> observable,Subscriber<T> subscriber ) {
        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(mFragment.<T>bindUntilEvent(FragmentEvent.DESTROY))//绑定生命周期,防止内存泄露
                .subscribe(subscriber);
    }


}

 里面将原始的网络请求方法抽了出来,并持有Act或者Frag的对象。只要子类继承了BaseModule,就可以在Module层为所欲为处理自己想要的逻辑了。

下面是具体的MainAct,MainPresenter,MainModelImp,如下所示:

public class MainAct extends BaseAct<MainView, MainPresenter> implements MainView {

    @BindView(R.id.bt)
    Button bt;
    @BindView(R.id.bt2)
    Button bt2;
    @BindView(R.id.bt3)
    Button bt3;
    @BindView(R.id.bt4)
    Button bt4;
    @BindView(R.id.bt5)
    Button bt5;
    @BindView(R.id.bt6)
    Button bt6;
    @BindView(R.id.tv)
    TextView tv;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_main;
    }

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


    /**
     * 点击事件 业务请求
     */
    @OnClick({R.id.bt, R.id.bt2, R.id.bt3, R.id.bt4, R.id.bt5, R.id.bt6})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.bt://get请求
                mPresenter.SimpleGet();
                break;
            case R.id.bt2://post请求
                mPresenter.SimplePost();
                break;
            case R.id.bt3://单图上传
                mPresenter.fileUpload();
                break;
            case R.id.bt4://多图上传
                mPresenter.fileUploads();
                break;
            case R.id.bt5://文件带进度下载
                mPresenter.fileDownLoad();
                break;
            case R.id.bt6://无网络取缓存,测试时将网络关闭
                mPresenter.simpleGetCache();
                break;
        }
    }

    //------------------------------业务回调---------------------------

    /**
     * get请求回调
     */
    @Override
    public void simpleGetCallback(String str) {
        tv.setText(String.valueOf("get成功请求返回数据: " + str));
    }


    /**
     * Post请求回调
     */
    @Override
    public void simplePostCallback(JsonObject jsonObject) {
        tv.setText(Stri
MVP(Model View Presenter)其实就是一种项目的整体框架,能让你的代码变得更加简洁,说起框架大家可能还会想到MVC、MVVM。由于篇幅原因,这里我们先不讲MVVM,先来看一下MVC。其实Android本身就采用的是MVC(Model View Controllor)模式、其中Model指的是数据逻辑和实体模型;View指的是布局文件、Controllor指的是Activity。对于很多Android初学者可能会有这样的经历,写代码的时候,不管三七二十一都往Activity中写,当然我当初也是这么干的,根本就没有什么框架的概念,只要能实现某一个功能就很开心了,没有管这么多。当然项目比较小还好,一旦项目比较大,你会发现,Activity所承担的任务其实是很重的,它既要负责页面的展示和交互,还得负责数据的请求和业务逻辑之类的工作,相当于既要打理家庭,又要教育自己调皮的孩子,真是又当爹又当妈。。。那该怎么办呢?这时候Presenter这个继父来到了这个家庭。Presenter对Activity说,我来了,以后你就别这么辛苦了,你就好好打理好View这个家,我专门来负责教育Model这孩子,有什么情况我会向你反映的。这时Activity流下了幸福的眼泪,从此,Model、View(Activity)、Presenter一家三口过上了幸福的生活。。。好了磕个药继续,由于Presenter(我们自己建的类)的出现,可以使View(Activity)不用直接和Model打交道,View(Activity)只用负责页面的显示和交互,剩下的和Model交互的事情都交给Presenter做,比如一些网络请求、数据的获取等,当Presenter获取到数据后再交给View(Activity)进行展示,这样,Activity的任务就大大减小了。这便是MVP(Model 还是指的数据逻辑和实体模型,View指的是Activity,P就是Presenter)框架的工作方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值