Retrofit与RxJava结合并进行封装

Retrofit和RxJava的优点有哪些在此就不赘述了,之前已经有数位大神在各个网站上发了若干文章,博主深感受益匪浅。 我在这里仅仅介绍一下我最近尝试的封装方法,至于为啥要封装,答:因为懒。。。

我们可以看一下使用 retrofit进行Http请求的代码:

okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(httpLoggingInterceptor)
                .build();
        retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .client(okHttpClient)
                .build();

        retrofitMethod = retrofit.create(RetrofitMethod.class);
        Call<List<User>> call = retrofitMethod.processList();

        call.enqueue(new Callback<List<User>>() {
            @Override
            public void onResponse(Call<List<User>> call, Response<List<User>> response) {
                if(response.body().size() > 0){
                    List<User> lt_userList = response.body();
                    Gson gson = new Gson();
                    String st_userList = gson.toJson(lt_userList);
                    Log.d("MainActivity", "result = " + st_userList);
                    tv_showText.setText(st_userList);
                }else{
                    Log.d("MainActivity", "no data");
                }
            }

            @Override
            public void onFailure(Call<List<User>> call, Throwable t) {
                Log.d("MainActivity", "failed");
            }
        });

当然,怎么可以少了build.gradle:

compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
    compile 'com.squareup.okhttp3:okhttp:3.4.1'
    compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
    compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'

    compile 'io.reactivex:rxjava:1.1.0'
    compile 'io.reactivex:rxandroid:1.1.0'

好了,一次请求看着还不错,至少感觉比异步任务要好一些,不过如果我再请求一个Result这个model的List呢?那么第二段代码又要写一次,将里面所有的User换成Result即可,but,总有你恶心的那一天,而且如果结合RxJava后,你会发现那个长度更恶心。。。

RxJava中会有指定观察者、被观察者、订阅等,还有指定在某个线程进行操作,这些内容大同小异,可以封装起来,于是乎有了第一版封装:

    public void processLists(Subscriber<List<User>> subscriber){
        retrofitMethod.processLists()
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }
RetrofitMethod.java

    @GET("user/list/")
    Observable<List<User>> processLists();

调用过程:

    private void getLists(){
        Subscriber<List<User>> subscriber = new Subscriber<List<User>>() {
            @Override
            public void onCompleted() {
                Toast.makeText(RetrofitThree.this, "complete", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onError(Throwable e) {
                Toast.makeText(RetrofitThree.this, "error", Toast.LENGTH_SHORT).show();
                Log.d("RetrofitThree", "error:" + e);
            }

            @Override
            public void onNext(List<User> users) {
                Gson gson = new Gson();
                String st_userList = gson.toJson(users);
                tv_resultThree.setText(st_userList);
            }
        };
        HttpManager3.getInstanc().processLists(subscriber);
    }
RxJava的订阅者中的方法主要有三个:onComplete(),当不再有新的onNext()发出时,触发onComplete()作为队列完结;onError(),事件队列异常,当它被触发时,队列自动终止,原则上讲onError()与onComplete()只能触发一个,并且是队列的最后一个;onNext(),回调的处理写在这里。

这次封装我们将关心的事件都放在明显的位置,准备做处理,将RxJava的一些设置封装了起来。但是细心的童鞋会发现:封装你妹啊!就封了一个方法!哥要调多个方法怎么办?!都封里面哥就疯了!!!

额,这个事情博主也考虑了,所以正确的姿势应该是这样的:

    public void processList(Observable observable , Subscriber subscriber){
        observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }
调用方法:
        Subscriber<List<User>> subscriber = new Subscriber<List<User>>() {
            @Override
            public void onCompleted() {
                Toast.makeText(RetrofitThree.this, "complete", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onError(Throwable e) {
                Log.d("RetrofitThree", "error" + e);
            }

            @Override
            public void onNext(List<User> users) {
                Toast.makeText(RetrofitThree.this, "ok", Toast.LENGTH_SHORT).show();
                Gson gson = new Gson();
                tv_resultThree.setText(gson.toJson(users));
            }
        };
        HttpManager3.getInstanc().processList(retrofitMethod.processLists() , subscriber);

诸位现在感觉怎么样?这次封装的套路没变,只不过是同时接收了被观察者和订阅者(观察者),这样就不会十个方法封十次了。 博主赶脚这次不会被打死了。

细心的小盆友又会说啦,介个onComplete()和onError()每次处理的方法基本都一样啊,我就关心onNext()。好吧,应大家之邀,把onComplete()和onError()也封装起来吧:

public class NewSubscriber3<T> extends Subscriber<T> {

    //    回调接口
    private HttpOnNextListener3 mSubscriberOnNextListener;
    //    弱引用防止内存泄露
    private WeakReference<Context> mActivity;

    private Context context;

    public NewSubscriber3(HttpOnNextListener3 mSubscriberOnNextListener, Context context) {
        this.mSubscriberOnNextListener = mSubscriberOnNextListener;
        this.mActivity = new WeakReference<>(context);
        this.context = context;
    }

    @Override
    public void onCompleted() {
        Toast.makeText(context, "subscriber completed", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onError(Throwable e) {
        Log.d("NewSubscriber3", "error:" + e);
    }

    @Override
    public void onNext(T t) {
        if (mSubscriberOnNextListener != null) {
            mSubscriberOnNextListener.onNext(t);
        }
    }
}
interface:

public interface HttpOnNextListener3<T>{
    void onNext(T t);
}

调用过程:

HttpOnNextListener3<List<User>> simpleOnNextListener = new HttpOnNextListener3<List<User>>() {
            @Override
            public void onNext(List<User> users) {
                Toast.makeText(RetrofitThree.this, "ok3", Toast.LENGTH_SHORT).show();
                Gson gson = new Gson();
                tv_resultThree.setText(gson.toJson(users));
            }
        };

        RetrofitMethod retrofitMethod = HttpManager3.getMethod();
        NewSubscriber3<List<User>> newSubscriber3 =
                new NewSubscriber3(simpleOnNextListener , this);
        HttpManager3.getInstanc().processList(retrofitMethod.processLists() , newSubscriber3);
最后再奉上神秘的HttpManager3.java:

package com.example.administrator.mytest.Retrofit3;

import com.example.administrator.mytest.Config.JavaConfig;
import com.example.administrator.mytest.HttpClient.RetrofitMethod;
import com.example.administrator.mytest.model.User;

import java.util.List;
import rx.Observable;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * Created by Ly on 2017/1/3.
 */

public class HttpManager3 {

    private volatile static HttpManager3 INSTANCE;
    private static long DEFUALT_TIMEOUT = 5000;
    private volatile static RetrofitMethod retrofitMethod;

    //构造方法私有
    private HttpManager3(){

    }

    private static RetrofitMethod Retro(){
        //手动创建一个OkHttpClient并设置超时时间
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(DEFUALT_TIMEOUT, TimeUnit.SECONDS);

        Retrofit retrofit = new Retrofit.Builder()
                .client(builder.build())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(JavaConfig.kfb_baseUrl)
                .build();

        retrofitMethod = retrofit.create(RetrofitMethod.class);
        return  retrofitMethod;
    }

    //获取单例
    public static HttpManager3 getInstanc(){
        if(INSTANCE == null){
            synchronized (HttpManager3.class){
                if(INSTANCE == null){
                    INSTANCE = new HttpManager3();
                }
            }
        }
        return INSTANCE;
    }

    public static RetrofitMethod getMethod(){
        if(retrofitMethod == null){
            synchronized (Retro()){
                if(retrofitMethod == null){
                    retrofitMethod = Retro();
                }
            }
        }
        return retrofitMethod;
    }

    public void processLists(Subscriber<List<User>> subscriber){
        retrofitMethod.processLists()
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }

    public void processList(Observable observable , Subscriber subscriber){
        observable.subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    }
}
博主的现学现卖到此告一段落,如有不足之处,还望大家指出~



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值