retrofit rx 一次封装多次调用统一处理

该封装解决一个api就要注入一个方法的问题,以及网络请求统一处理。之前看了很多封装都不是自己想要的,于是自己想了个比较笨的方法。

1、定义我们简洁的ApiService

public interface BaseApiService {
    @GET()
    Observable<ResponseBody> get(@Url String url, @QueryMap Map<String, String> maps);

    @GET()
    Observable<ResponseBody> get(@Url String url);

    @Streaming
    @GET
    Observable<ResponseBody> downloadApp(@Url String fileUrl);

    @FormUrlEncoded
    @POST()
    Observable<ResponseBody> post(@Url String url, @FieldMap Map<String, String> map);

}

2、定义ApiManager

使用泛型定义请求接口get、post、、、,好处是不管api有多少我们都可以走一个通道,不用重新写方法,处理思路是Gosn解析:
在service中定义默认返回http3的Response,在ApiManager中定义一个转换Observable方法,把Response.string返回内容使用Gson进行包装。根据传来的参数类型,使用RX操作符flatMap进行转换我们对应的s实体类型。

public class BaseApiManager {

    /**
     * server 请求接口
     */
    private BaseApiService apiServer;
    /**
     * 单例类对象
     */
    private static BaseApiManager instance;

    private BaseApiManager(){
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .retryOnConnectionFailure(true)
                .connectTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS);
        builder.addInterceptor(new ReceivedCookiesInterceptor(App.getInstance()))
                .addInterceptor(new AddCookiesInterceptor(App.getInstance()))
                .addNetworkInterceptor(new StethoInterceptor());

        Retrofit.Builder retrofit = new Retrofit.Builder()
                .baseUrl(MyConstant.BASE_URI)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create(new Gson()));
        retrofit.client(builder.build());
        apiServer = retrofit.build().create(BaseApiService.class);
    }


    public static synchronized BaseApiManager getApi(){
        if(instance==null){
            instance=new BaseApiManager();
        }
        return instance;
    }


    /**
     * 执行网络请求
     * @param url 已经指定了base url 可以传目录
     * @param queryMap 请求参数
     * @param tClass    返回对象的泛型
     * @param <T>       泛型
     * @return   具体Observable 对象
     */
    public <T> Observable<T> executeGet(String url, final Class<T> tClass, HashMap<String,String> queryMap){
        Observable<T> ob=apiServer.get(url,queryMap) .flatMap(new Func1<ResponseBody, Observable<T>>() {
                @Override
                public Observable<T> call(ResponseBody body) {
                    T t=null;
                    try {
                        String rs=body.string();
                        Gson gson=new Gson();
                        t=gson.fromJson(rs,tClass);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return createObserver(t);
                }
            });

        return ob.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 执行网络请求
     * @param url 已经指定了base url 可以传目录
     * @param tClass    返回对象的泛型
     * @param <T>       泛型
     * @return   具体Observable 对象
     */
    public <T> Observable<T> executeGet(String url, final Class<T> tClass){
        Observable<T> ob=apiServer.get(url) .flatMap(new Func1<ResponseBody, Observable<T>>() {
            @Override
            public Observable<T> call(ResponseBody body) {
                T t=null;
                try {
                    String rs=body.string();
                    Gson gson=new Gson();
                    t=gson.fromJson(rs,tClass);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return createObserver(t);
            }
        });

        return ob.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 执行网络请求
     * @param url 已经指定了base url 可以传目录
     * @param queryMap 请求参数
     * @param tClass    返回对象的泛型
     * @param <T>       泛型
     * @return   具体Observable 对象
     */
    public <T> Observable<T> executePost(String url, final Class<T> tClass, HashMap<String,String> queryMap){
        Observable<T> ob=apiServer.post(url,queryMap) .flatMap(new Func1<ResponseBody, Observable<T>>() {
            @Override
            public Observable<T> call(ResponseBody body) {
                T t=null;
                try {
                    String rs=body.string();
                    Gson gson=new Gson();
                    t=gson.fromJson(rs,tClass);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return createObserver(t);
            }
        });

        return ob.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 创建一个泛型的Observable
     * @param t 泛型
     * @param <T>Observable 返回指定的泛型
     * @return
     */
    private <T> Observable<T> createObserver(final T t) {
        return Observable.create(new Observable.OnSubscribe<T>() {
            @Override
            public void call(Subscriber<? super T> subscriber) {
                if(t==null){
                    subscriber.onError(new Throwable("t 解析是空的"));
                }else{
                    subscriber.onNext(t);
                }
                subscriber.onCompleted();
            }
        });
    }
    }

3 定义一个实体解析的父类

使得我们需要请求返回的对象都继承该类,以便网络请求有的地方统一处理

public class BaseResponse{

    /**
     * 服务器约定的成功码
     */
    private int ok_code=1;

    private String message;
    private int result;
    private int code;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getResult() {
        return result;
    }

    public void setResult(int result) {
        this.result = result;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

 public boolean isOk(){
        return ok_code==result;
    }
}

4 对网络请求统一处理,这个地方其他作者写的比较好,我作了下方便自己的一些修改

在订阅的时候传入Subscriber,重写方法 onStart 、onError、onComplet、onNext。定义一个接口,该接口主要包含两个方法 onSuccess,onFailure 或许还可以包含一个_onError方法作为回掉

/**
 * Created by Administrator on 2017/1/9 0009.
 */

public class BaseSubscriber<T extends BaseResponse> extends Subscriber<T> {
    private Context context;
    private String TAG;
    private Dialog dialog;
    private CallBack callBack;

    TextView tv;
    public BaseSubscriber(@Nullable Context context, @NonNull CallBack callBack) {
        this.context = context;
        this.callBack=callBack;
        TAG = getClass().getSimpleName();
        if (context != null) {
            dialog=new Dialog(context,R.style.fullScreen);
            View v= LayoutInflater.from(context).inflate(R.layout.dialog_progress,null,false);
            tv=(TextView) v.findViewById(R.id.loading_text);
            tv.setText("请稍等");
            dialog.setContentView(v);
            dialog.setCancelable(false);
        }
    }

    private Toast toast;
    private void showToast(String msg,boolean notifyNetwork) {
        if(context==null && !notifyNetwork){
            Log.e(TAG,msg);
            return;
        }
        if (toast== null) {
            toast=Toast.makeText(App.getInstance(), msg, Toast.LENGTH_SHORT);
        }else {
            toast.setText(msg);
        }
        toast.show();
        Log.i(TAG, msg);
    }

    @Override
    public void onStart() {
        super.onStart();
        boolean isNetAvailable = NetUtil.isNetworkAvailable();
        Log.i(TAG, "  network is available " + isNetAvailable);
        if (!isNetAvailable) {
            showToast("亲,网络不可用,请检查网络后再尝试!",true);
            onCompleted();
            return;
        }
        if (dialog != null){
            dialog.show();
        }
    }

    @Override
    public void onCompleted() {
        Log.i(TAG);
        if(dialog!=null){
            dialog.dismiss();
        }
    }

    @Override
    public void onError(Throwable e) {
        e.printStackTrace();
        if (dialog != null)
            dialog.dismiss();
        String error="";
        if (e instanceof HttpException) {
            HttpException exception = (HttpException) e;
            try {
                error = exception.response().errorBody().string();
                Log.e(TAG, "出错了 " + error);
            } catch (IOException e1) {
                e1.printStackTrace();
                error = e1.getMessage();
                Log.e(TAG, "出错了 " + error);
            }
        }
    }

    @Override
    public void onNext(T t){
        if(t.isOk()){
            callBack.success(t);
        }else{
            Log.i(TAG,"request="+t.toString());
            callBack.failure(t.getMessage(),t.getCode(),t.getResult());
        }
    }


    public interface CallBack<T>{
        void success(T bean);
        void failure(String failure,int code,int result);
    }
}

5 调用

如果ApiManager中定义几个公共重载方法或者统一处理参数,就不用每次传个Map过去,懒人专属。另外如果多个ApiService的话,可以在APiManger定义的时候写为泛型,动态传入。

        HashMap<String, String> map = new HashMap<>();
        map.put("phone",ShareUtils.getUserPhone());
        map.put("password", ShareUtils.getPassword());
        map.put("loginDevice", "android");
        BaseApiManager.getApi().executePost("login",UserBean.class,map)
                .subscribe(new BaseSubscriber<UserBean>(null,new BaseSubscriber.CallBack<UserBean>() {
                    @Override
                    public void success(UserBean bean) {
                        Log.i("----","name------------"+bean.getBody().getUsername());
                        ShareUtils.saveUser(bean.getBody());
                        startActivity(new Intent(WelcomeActivity.this, MainActivity.class));
                        finish();
                    }

                    @Override
                    public void failure(String failure, int code, int result) {
                        Toast.makeText(WelcomeActivity.this,failure+"  from login",Toast.LENGTH_SHORT).show();
                        startActivity(new Intent(WelcomeActivity.this, MainActivity.class));
                        finish();
                    }
                }));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值