OKHttp+RxJava+RxAndroid MVP详解

一.主流的技术框架简介

Android开发中常用的技术架构有三种,MVC,MVP,MVVM。具体讲解

1. MVC

<1> M:Model:模型层

            主要用来获取数据,数据的来源包括接口获取,数据库获取,SharedPreferences获取等等途径。并将其解析成Bean对象回调给Controller层。

<2> V:View:视图层

            主要用来绘制各个视图,即Activity/Fragment对应的布局XML文件。

<3> C:Controller:控制层

            主要接收Model层的回调,控制View层的显示。Activity/Fragment。

MVC中虽然Activity/Fragment是Controller层,来接收Model层的数据回调,但是由于布局的初始化,显示隐藏以及各种布局的切换等等操作也要在Activity/Fragment中完成。所以Activity/Fragment在MVC的模式下即相当于Controller层又相当于View层。当逻辑复杂时Activity/Fragment中的代码就会异常多而且会特别混乱。所以MVP模式诞生了。

2. MVP

MVP作为MVC的演化,解决了MVC上述的缺点。

<1> M:Model:模型层

            主要用来获取数据,数据的来源包括接口获取,数据库获取,SharedPreferences获取等等途径。并将其解析成Bean对象回调给Presenter层。

<2> V:View:视图层

            主要接收用户指令(用户点击某个按钮请求数据,或者用户进入某个页面请求数据)。然后调用Presenter层的相关方法进行获取数据的操作。然后接收Presenter层获取各种数据的结果回调,显示不同的View操作(比如有数据显示列表,无数据显示暂无数据)。

<3> P:Presenter:呈现层

            主要接收View层的指令然后调用Model层的相关方法,去进行获取接口数据或是获取数据库数据等等的操作。然后接收Model层操作后的各种结果回调给View层,做不同的操作。

MVP模式中,View层和Model层是相互独立没有关联的,两个的关联需要借助Presenter层。

3. MVVM

<1> 非Androidx项目DataBinding 基础讲解_jianning-wu的博客-优快云博客

<2> 非Androidx项目DataBinding RecyclerView使用_jianning-wu的博客-优快云博客

<3> 非Androidx项目DataBinding ListView使用_不使用androidx怎么用 databinding 兼容性问题_jianning-wu的博客-优快云博客

二.代码实现

1.Gradle依赖 RxJava&RxAndroid一起使用必须版本相同 都是1.X版本或者2.X版本

//RxJava
implementation 'io.reactivex:rxjava:1.3.2'

//RxAndroid
implementation 'io.reactivex:rxandroid:1.2.1'
    
//OkHttp
implementation 'com.squareup.okhttp3:okhttp:3.9.0'

2.Model层(Get请求&Post请求&下载图片)

package com.wjn.networkdemo.okhttp.rx;

import android.text.TextUtils;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

import static com.wjn.networkdemo.okhttp.rx.RxSaveKey.GET_KEY;

/**
 * Get方法Model层
 */

public class GetModel {

    private RxAndroidOkHttp mRxAndroidOkHttp;//RxAndroidOkhttp对象
    private Observable mObservable = null;
    private String mGetUrl = "http://fanyi.youdao.com/openapi.do?keyfrom=imoocdict123456&key=324273592&type=data&doctype=json&version=1.1&q=blue";

    private GetPresenter mGetPresenter;

    public GetModel(GetPresenter presenter) {
        mRxAndroidOkHttp = RxAndroidOkHttp.getInstance();
        mGetPresenter = presenter;
    }

    /**
     * Get请求
     */

    public void getServiceData() {
        if (null != mRxAndroidOkHttp) {
            //1.获取Observable被观察者
            mObservable = mRxAndroidOkHttp.get(mGetUrl);
            if (null != mObservable) {
                //2.创建观察者
                Subscriber<String> mSubscriber = new Subscriber<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        jsonData("");
                    }

                    @Override
                    public void onNext(String s) {
                        jsonData(s);
                    }
                };

                /**
                 * 3.观察者&被观察者关联
                 * subscribeOn:设置被观察者所在的线程 Schedulers.io() IO线程
                 * observeOn:设置观察者所在的线程 AndroidSchedulers.mainThread() UI主线程
                 * */

                Subscription subscription = mObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(mSubscriber);

                /**
                 * 4.保存订阅关系以便在合适时机取消订阅关系 避免内存泄漏
                 * */

                RxAndroidOkHttp.getInstance().saveSubscription(GET_KEY, subscription);
            }
        }
    }

    /**
     * Json数据解析
     */

    private void jsonData(String result) {
        Log.d("TAG", "result----:" + result);
        MyBean bean = new MyBean();
        if (!TextUtils.isEmpty(result)) {
            String translation = "";
            String basic = "";
            try {
                JSONObject jsonObject = new JSONObject(result);
                translation = jsonObject.optString("translation");
                basic = jsonObject.optString("basic");
            } catch (JSONException ex) {
                ex.printStackTrace();
            }

            bean.setTranslation(translation);
            bean.setBasic(basic);
        } else {
            bean.setTranslation("");
            bean.setBasic("");
        }

        //最终刷新UI
        if (null != mGetPresenter) {
            mGetPresenter.updateServiceUI(bean);
        }
    }

    /**
     * 取消订阅
     */

    public void unSubscribe() {
        RxAndroidOkHttp.getInstance().unSubscribe(GET_KEY);
    }

}

package com.wjn.networkdemo.okhttp.rx;

import android.text.TextUtils;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.Map;

import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

import static com.wjn.networkdemo.okhttp.rx.RxSaveKey.POST_KEY;

/**
 * Post方法Model层
 */

public class PostModel {

    private RxAndroidOkHttp mRxAndroidOkHttp;//RxAndroidOkhttp对象
    private Observable mObservable = null;
    private String mPostUrl = "http://fanyi.youdao.com/openapi.do";

    private PostPresenter mPostPresenter;


    public PostModel(PostPresenter presenter) {
        mRxAndroidOkHttp = RxAndroidOkHttp.getInstance();
        mPostPresenter = presenter;
    }

    /**
     * Post请求
     */

    public void postServiceData(Map<String, String> params) {
        if (null != mRxAndroidOkHttp) {
            //1.获取Observable被观察者
            mObservable = mRxAndroidOkHttp.post(mPostUrl, params);
            if (null != mObservable) {
                //2.创建观察者
                Subscriber<String> mSubscriber = new Subscriber<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        jsonData("");
                    }

                    @Override
                    public void onNext(String s) {
                        jsonData(s);
                    }
                };

                /**
                 * 3.观察者&被观察者关联
                 * subscribeOn:设置被观察者所在的线程 Schedulers.io() IO线程
                 * observeOn:设置观察者所在的线程 AndroidSchedulers.mainThread() UI主线程
                 * */

                Subscription subscription = mObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(mSubscriber);

                /**
                 * 4.保存订阅关系以便在合适时机取消订阅关系 避免内存泄漏
                 * */

                RxAndroidOkHttp.getInstance().saveSubscription(POST_KEY, subscription);
            }
        }
    }

    /**
     * Json数据解析
     */

    private void jsonData(String result) {
        Log.d("TAG", "result----:" + result);
        MyBean bean = new MyBean();
        if (!TextUtils.isEmpty(result)) {
            String translation = "";
            String basic = "";
            try {
                JSONObject jsonObject = new JSONObject(result);
                translation = jsonObject.optString("translation");
                basic = jsonObject.optString("basic");
            } catch (JSONException ex) {
                ex.printStackTrace();
            }

            bean.setTranslation(translation);
            bean.setBasic(basic);
        } else {
            bean.setTranslation("");
            bean.setBasic("");
        }

        //最终刷新UI
        if (null != mPostPresenter) {
            mPostPresenter.updateServiceUI(bean);
        }
    }

    /**
     * 取消订阅
     */

    public void unSubscribe() {
        RxAndroidOkHttp.getInstance().unSubscribe(POST_KEY);
    }

}

package com.wjn.networkdemo.okhttp.rx;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

import static com.wjn.networkdemo.okhttp.rx.RxSaveKey.LOAD_PICTURE_KEY;

/**
 * 下载图片方法Model层
 */

public class LoadPictureModel {

    private RxAndroidOkHttp mRxAndroidOkHttp;//RxAndroidOkhttp对象
    private Observable mObservable = null;
    private String mLoadPictureUrl = "http://upload.site.cnhubei.com/2016/0117/1453000952567.jpg";

    private LoadPicturePresenter mLoadPicturePresenter;

    public LoadPictureModel(LoadPicturePresenter presenter) {
        mRxAndroidOkHttp = RxAndroidOkHttp.getInstance();
        mLoadPicturePresenter = presenter;
    }

    /**
     * 下载图片请求
     */

    public void loadPictureServiceData() {
        if (null != mRxAndroidOkHttp) {
            //1.获取Observable被观察者
            mObservable = mRxAndroidOkHttp.loadImageViewByUrl(mLoadPictureUrl);
            if (null != mObservable) {
                //2.创建观察者
                Subscriber<byte[]> mSubscriber = new Subscriber<byte[]>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        jsonData(null);
                    }

                    @Override
                    public void onNext(byte[] bytes) {
                        jsonData(bytes);
                    }
                };

                /**
                 * 3.观察者&被观察者关联
                 * subscribeOn:设置被观察者所在的线程 Schedulers.io() IO线程
                 * observeOn:设置观察者所在的线程 AndroidSchedulers.mainThread() UI主线程
                 * */

                Subscription subscription = mObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(mSubscriber);

                /**
                 * 4.保存订阅关系以便在合适时机取消订阅关系 避免内存泄漏
                 * */

                RxAndroidOkHttp.getInstance().saveSubscription(LOAD_PICTURE_KEY, subscription);
            }
        }
    }

    /**
     * Json数据解析
     */

    private void jsonData(byte[] bytes) {
        Bitmap bitmap = null;
        if (null != bytes) {
            bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        }

        //最终刷新UI
        if (null != mLoadPicturePresenter) {
            mLoadPicturePresenter.updateServiceUI(bitmap);
        }
    }

    /**
     * 取消订阅
     */

    public void unSubscribe() {
        RxAndroidOkHttp.getInstance().unSubscribe(LOAD_PICTURE_KEY);
    }

}

3.Presenter层(Get请求&Post请求&下载图片)

package com.wjn.networkdemo.okhttp.rx;

/**
 * Get方法Presenter层
 */

public class GetPresenter {

    private GetCallBack mGetCallBack;
    private GetModel mGetModel;

    public GetPresenter(GetCallBack callBack) {
        mGetCallBack = callBack;
        mGetModel = new GetModel(this);
    }

    /**
     * Get请求
     */

    public void getServiceData() {
        if (null != mGetModel) {
            mGetModel.getServiceData();
        }
    }

    /**
     * 刷新UI
     */

    public void updateServiceUI(MyBean bean) {
        if (null == mGetCallBack || null == bean) {
            return;
        }

        mGetCallBack.getResult(bean);
    }

    /**
     * 取消订阅
     */

    public void unSubscribe() {
        if (null != mGetModel) {
            mGetModel.unSubscribe();
        }
    }

    /**
     * 回调
     */

    public interface GetCallBack {
        void getResult(MyBean bean);
    }

}

package com.wjn.networkdemo.okhttp.rx;

import java.util.Map;

/**
 * Post方法Presenter层
 */

public class PostPresenter {

    private PostCallBack mPostCallBack;
    private PostModel mPostModel;

    public PostPresenter(PostCallBack callBack) {
        mPostCallBack = callBack;
        mPostModel = new PostModel(this);
    }

    /**
     * Post请求
     */

    public void postServiceData(Map<String, String> params) {
        if (null != mPostModel) {
            mPostModel.postServiceData(params);
        }
    }

    /**
     * 刷新UI
     */

    public void updateServiceUI(MyBean bean) {
        if (null == mPostCallBack || null == bean) {
            return;
        }

        mPostCallBack.postResult(bean);
    }

    /**
     * 取消订阅
     */

    public void unSubscribe() {
        if (null != mPostModel) {
            mPostModel.unSubscribe();
        }
    }

    /**
     * 回调
     */

    public interface PostCallBack {
        void postResult(MyBean bean);
    }

}

package com.wjn.networkdemo.okhttp.rx;

import android.graphics.Bitmap;

/**
 * 下载图片方法Presenter层
 */

public class LoadPicturePresenter {

    private LoadPictureCallBack mLoadPictureCallBack;
    private LoadPictureModel mLoadPictureModel;

    public LoadPicturePresenter(LoadPictureCallBack callBack) {
        mLoadPictureCallBack = callBack;
        mLoadPictureModel = new LoadPictureModel(this);
    }

    /**
     * 下载图片请求
     */

    public void loadPictureServiceData() {
        if (null != mLoadPictureModel) {
            mLoadPictureModel.loadPictureServiceData();
        }
    }

    /**
     * 刷新UI
     */

    public void updateServiceUI(Bitmap bitmap) {
        if (null == mLoadPictureCallBack || null == bitmap) {
            return;
        }

        mLoadPictureCallBack.LoadPictureResult(bitmap);
    }

    /**
     * 取消订阅
     */

    public void unSubscribe() {
        if (null != mLoadPictureModel) {
            mLoadPictureModel.unSubscribe();
        }
    }

    /**
     * 回调
     */

    public interface LoadPictureCallBack {
        void LoadPictureResult(Bitmap bitmap);
    }

}

4.View层

package com.wjn.networkdemo.okhttp.rx;

import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

import androidx.appcompat.app.AppCompatActivity;

import com.wjn.networkdemo.R;

import java.util.HashMap;
import java.util.Map;

public class OkHttpRxActivity extends AppCompatActivity implements GetPresenter.GetCallBack, PostPresenter.PostCallBack, LoadPicturePresenter.LoadPictureCallBack {

    private ImageView mImageView;

    private GetPresenter mGetPresenter;
    private PostPresenter mPostPresenter;
    private LoadPicturePresenter mLoadPicturePresenter;

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

        mImageView = findViewById(R.id.activity_okhttp_rx_imageview);

        mGetPresenter = new GetPresenter(this);
        mPostPresenter = new PostPresenter(this);
        mLoadPicturePresenter = new LoadPicturePresenter(this);

        //Get请求
        findViewById(R.id.activity_okhttp_rx_textview1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getData();
            }
        });

        //Post请求
        findViewById(R.id.activity_okhttp_rx_textview2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Map<String, String> params = new HashMap<>();
                params.put("keyfrom", "imoocdict123456");
                params.put("key", "324273592");
                params.put("type", "data");
                params.put("doctype", "json");
                params.put("version", "1.1");
                params.put("q", "red");
                postData(params);
            }
        });

        //下载图片
        findViewById(R.id.activity_okhttp_rx_textview3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                loadPicture();
            }
        });

    }

    /**
     * OkHttp Get请求
     */

    private void getData() {
        if (null != mGetPresenter) {
            mGetPresenter.getServiceData();
        }
    }

    /**
     * OkHttp Post请求
     */

    private void postData(final Map<String, String> params) {
        if (null != mPostPresenter) {
            mPostPresenter.postServiceData(params);
        }
    }

    /**
     * OkHttp 下载图片
     */

    private void loadPicture() {
        if (null != mLoadPicturePresenter) {
            mLoadPicturePresenter.loadPictureServiceData();
        }
    }

    /**
     * Get请求回调
     */

    @Override
    public void getResult(MyBean bean) {
        if (null == bean) {
            return;
        }

        String translation = bean.getTranslation();
        String basic = bean.getBasic();
        String result = "Translation:" + translation + "  Basic:" + basic;
        Log.d("OkHttpRxActivity", "Get请求回调 result----:" + result);
        Log.d("OkHttpRxActivity", "Get请求回调 线程----:" + Thread.currentThread().getName());
    }

    /**
     * Post请求回调
     */

    @Override
    public void postResult(MyBean bean) {
        if (null == bean) {
            return;
        }

        String translation = bean.getTranslation();
        String basic = bean.getBasic();
        String result = "Translation:" + translation + "  Basic:" + basic;
        Log.d("OkHttpRxActivity", "Post请求回调 result----:" + result);
        Log.d("OkHttpRxActivity", "Post请求回调 线程----:" + Thread.currentThread().getName());
    }

    /**
     * 下载图片回调
     */

    @Override
    public void LoadPictureResult(Bitmap bitmap) {
        if (null != bitmap && !bitmap.isRecycled()) {
            mImageView.setImageBitmap(bitmap);
        }
        Log.d("OkHttpRxActivity", "下载图片回调 线程----:" + Thread.currentThread().getName());
    }

    /**
     * onDestroy方法 测试 具体每个接口取消订阅在自己接口对应的地方取消即可
     */

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (null != mGetPresenter) {
            mGetPresenter.unSubscribe();
        }

        if (null != mPostPresenter) {
            mPostPresenter.unSubscribe();
        }

        if (null != mLoadPicturePresenter) {
            mLoadPicturePresenter.unSubscribe();
        }
    }
}

5.工具类

package com.wjn.networkdemo.okhttp.rx;

import android.text.TextUtils;
import android.util.Log;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.subscriptions.CompositeSubscription;

public class RxAndroidOkHttp {

    private OkHttpClient mOkHttpClient;//OkHttpClient 对象
    private static RxAndroidOkHttp mRxAndroidOkHttp = null;//单例对象
    private HashMap<String, CompositeSubscription> mHashMap;//订阅关系集合

    /**
     * 构造方法
     */

    private RxAndroidOkHttp() {
        //创建OkHttp对象 以及连接,读,取超时时间
        mOkHttpClient = new OkHttpClient.Builder()
                .connectTimeout(20, TimeUnit.SECONDS)//连接时间
                .readTimeout(20, TimeUnit.SECONDS)//读时间
                .writeTimeout(20, TimeUnit.SECONDS)//写时间
                .retryOnConnectionFailure(true)//连接失败后是否重新连接
                .build();
        //创建存储订阅关系的集合
        mHashMap = new HashMap<>();
    }

    /**
     * 获取此单例类对象的方法
     */

    public static RxAndroidOkHttp getInstance() {
        if (null == mRxAndroidOkHttp) {//单例对象为空
            synchronized (RxAndroidOkHttp.class) {
                if (null == mRxAndroidOkHttp) {
                    mRxAndroidOkHttp = new RxAndroidOkHttp();
                }
            }
        }
        return mRxAndroidOkHttp;
    }

    /**
     * Get方法
     */

    public Observable<String> get(final String url) {
        //创建被观察者
        Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                final Subscriber mSubscriber = subscriber;
                if (!mSubscriber.isUnsubscribed()) { //没有取消订阅的时候
                    //1.创建Request对象 构建一个具体的网络请求对象 包括具体的请求url&请求头&请求体等等
                    Request request = new Request.Builder().url(url).get().build();
                    if (null != mOkHttpClient) {
                        //2.获取Call对象 将具体的网络请求与执行请求的实体进行绑定,形成一个具体的正式的可执行实体
                        Call call = mOkHttpClient.newCall(request);
                        //3.Call对象进行网络请求 enqueue异步  execute同步一般不用
                        call.enqueue(new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                //通知订阅者的错误信息
                                mSubscriber.onError(e);
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                if (null != response && response.isSuccessful()) {//通知订阅者的成功信息
                                    mSubscriber.onNext(response.body().string());
                                } else {//通知订阅者的错误信息
                                    IOException exception = new IOException("Get请求onResponse方法回调异常");
                                    mSubscriber.onError(exception);
                                }
                                //通知完毕
                                mSubscriber.onCompleted();
                            }
                        });
                    }
                }
            }
        });
        return observable;
    }

    /**
     * Post方法
     */

    public Observable<String> post(final String url, final Map<String, String> params) {
        //创建被观察者
        Observable<String> observable = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                final Subscriber mSubscriber = subscriber;
                if (!mSubscriber.isUnsubscribed()) {//没有取消订阅的时候
                    //1.获取FormBody.Builder对象
                    FormBody.Builder builder = new FormBody.Builder();
                    //2.遍历params 将其放入到FormBody.Builder 对象
                    if (params != null && !params.isEmpty()) {
                        for (Map.Entry<String, String> entry : params.entrySet()) {
                            builder.add(entry.getKey(), entry.getValue());
                        }
                    }
                    //3.获取RequestBody 对象
                    RequestBody requestBody = builder.build();
                    //4.创建Request对象 构建一个具体的网络请求对象 包括具体的请求url&请求头&请求体等等
                    Request request = new Request.Builder().url(url).post(requestBody).build();
                    if (mOkHttpClient != null) {
                        //5.获取Call对象 将具体的网络请求与执行请求的实体进行绑定,形成一个具体的正式的可执行实体
                        Call call = mOkHttpClient.newCall(request);
                        //6.Call对象进行网络请求 enqueue异步  execute同步一般不用
                        call.enqueue(new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                //通知订阅者的错误信息
                                mSubscriber.onError(e);
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                if (null != response && response.isSuccessful()) {//通知订阅者的成功信息
                                    mSubscriber.onNext(response.body().string());
                                } else {
                                    IOException exception = new IOException("Post请求onResponse方法回调异常");
                                    mSubscriber.onError(exception);
                                }
                                //通知完毕
                                mSubscriber.onCompleted();
                            }
                        });
                    }
                }
            }
        });
        return observable;
    }

    /**
     * 下载图片 Get方法
     */

    public Observable<byte[]> loadImageViewByUrl(final String url) {
        //创建被观察者
        Observable<byte[]> observable = Observable.create(new Observable.OnSubscribe<byte[]>() {
            @Override
            public void call(Subscriber<? super byte[]> subscriber) {
                final Subscriber mSubscriber = subscriber;
                if (!mSubscriber.isUnsubscribed()) { //没有取消订阅的时候
                    //1.创建Request对象 构建一个具体的网络请求对象 包括具体的请求url&请求头&请求体等等
                    Request request = new Request.Builder().url(url).get().build();
                    if (null != mOkHttpClient) {
                        //2.获取Call对象 将具体的网络请求与执行请求的实体进行绑定,形成一个具体的正式的可执行实体
                        Call call = mOkHttpClient.newCall(request);
                        //3.Call对象进行网络请求 enqueue异步  execute同步一般不用
                        call.enqueue(new Callback() {
                            @Override
                            public void onFailure(Call call, IOException e) {
                                //通知订阅者的错误信息
                                mSubscriber.onError(e);
                            }

                            @Override
                            public void onResponse(Call call, Response response) throws IOException {
                                if (null != response && response.isSuccessful()) {//通知订阅者的成功信息
                                    byte[] data = response.body().bytes();
                                    if (data != null) {
                                        mSubscriber.onNext(data);
                                    } else {
                                        IOException exception = new IOException("图片下载onResponse方法数据异常");
                                        mSubscriber.onError(exception);
                                    }
                                } else {
                                    IOException exception = new IOException("图片下载onResponse方法回调异常");
                                    mSubscriber.onError(exception);
                                }
                                //通知完毕
                                mSubscriber.onCompleted();
                            }
                        });
                    }
                }
            }
        });
        return observable;
    }

    /**
     * 保存Subscription
     */

    public void saveSubscription(String key, Subscription subscription) {
        if (TextUtils.isEmpty(key) || null == subscription) {
            return;
        }

        if (mHashMap == null) {
            mHashMap = new HashMap<>();
        }

        if (mHashMap.get(key) != null) {
            mHashMap.get(key).add(subscription);
        } else {
            CompositeSubscription compositeSubscription = new CompositeSubscription();
            compositeSubscription.add(subscription);
            mHashMap.put(key, compositeSubscription);
        }
    }

    /**
     * 取消订阅
     */

    public void unSubscribe(String key) {
        if (null == mHashMap || TextUtils.isEmpty(key) || !mHashMap.containsKey(key)) {
            return;
        }
        Log.d("TAG", "取消订阅 key----:" + key);

        CompositeSubscription compositeSubscription = mHashMap.get(key);
        if (compositeSubscription != null) {
            compositeSubscription.unsubscribe();
        }

        mHashMap.remove(key);
    }

}

6.补充

<1> RxJava GitHub地址:GitHub - ReactiveX/RxJava: RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.

<2> RxAndroid GitHub地址:GitHub - ReactiveX/RxAndroid: RxJava bindings for Android

<3> 指定被观察者 生产事件的线程。

observable.subscribeOn(Schedulers.newThread())

<4> 指定观察者 接收 & 响应事件的线程。

observable.observeOn(AndroidSchedulers.mainThread())

<5> RxJava线程切换具体实现

RxJava详解(基于2.X版本的功能操作符)_jianning-wu的博客-优快云博客


 

三.注意事项

1.MVP内存泄漏详见

代码混淆_jianning-wu的博客-优快云博客

2.RxJava详见

https://blog.youkuaiyun.com/weixin_37730482/category_10501619.html

3.RxBus详见

RxBus详解(基于1.X版本)_jianning-wu的博客-优快云博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值