Retrofit2+RxJava2封装

Retrofit2+RxJava的封装


欢迎阅读

1.首先在gradle文件中添加retrofit和rxjava的依赖

implementation 'io.reactivex.rxjava2:rxjava:2.1.12'  // 必要rxjava2依赖
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'  // 必要rxandrroid依赖,切线程时需要用到
implementation 'com.google.code.gson:gson:2.8.2'  
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'  // 必要依赖,和Rxjava结合必须用到
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'  // 必要依赖,解析json字符所用
implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'  //非必要依赖, log依赖,如果需要打印OkHttpLog需要添加

2.在AndroidManifest.xml清单文件中加入网络权限

<uses-permission android:name="android.permission.INTERNET" />

3.创建网络请求的接口类ApiService

public interface ApiService {
    /**
     *查询历史天气
     * @param key
     * @param city_id
     * @param date
     * @return
     */
    @GET("weather")
    Flowable<HttpResult<HistroyResult>> getHistroy(@Query("key") String key,
                                   @Query("city_id") String city_id,
                                   @Query("weather_date") String date);
    //
}

@get表示get请求,如果是post请求的话就是@post

4.接下来我们来看一下接口返回数据的格式

  • 这里我使用的是聚合数据上的历史天气返回的Json数据
  • 首先,在解析服务器返回的数据时,需要和服务器统一返回Json格式,下面的json格式就是很标准的。

聚合使用很简单,不做说明

{
    "reason": "查询成功",
    "result": {
        "city_id": "1157",
        "city_name": "苏州",
        "weather_date": "2017-07-15",
        "day_weather": "多云",
        "night_weather": "晴",
        "day_temp": "33℃",
        "night_temp": "25℃",
        "day_wind": "无持续风向",
        "day_wind_comp": "≤3级",
        "night_wind": "无持续风向",
        "night_wind_comp": "≤3级",
        "day_weather_id": "01",
        "night_weather_id": "00"
    },
    "error_code": 0
}

4.1 创建一个通用返回格式的bean类 HttpResult

public class HttpResult<T> implements Serializable {

    /**
     * reason : 查询成功
     * result : {"city_id":"1157","city_name":"苏州","weather_date":"2017-07-15","day_weather":"多云","night_weather":"晴","day_temp":"33℃","night_temp":"25℃","day_wind":"无持续风向","day_wind_comp":"≤3级","night_wind":"无持续风向","night_wind_comp":"≤3级","day_weather_id":"01","night_weather_id":"00"}
     * error_code : 0
     */
    private String reason;//返回的message
    private int error_code;//返回的code
    private T result;//想要的具体数据

    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }

    public int getError_code() {
        return error_code;
    }

    public void setError_code(int error_code) {
        this.error_code = error_code;
    }

    public T getResults() {
        return result;
    }

    public void setResults(T results) {
        this.result = results;
    }
}

4.2再创建具体的天气信息bean,也就是上面的T部分HistroyResult

public class HistroyResult {

    /**
     * city_id : 1157
     * city_name : 苏州
     * weather_date : 2017-07-15
     * day_weather : 多云
     * night_weather : 晴
     * day_temp : 33℃
     * night_temp : 25℃
     * day_wind : 无持续风向
     * day_wind_comp : ≤3级
     * night_wind : 无持续风向
     * night_wind_comp : ≤3级
     * day_weather_id : 01
     * night_weather_id : 00
     */

    private String city_id;
    private String city_name;
    private String weather_date;
    private String day_weather;
    private String night_weather;
    private String day_temp;
    private String night_temp;
    private String day_wind;
    private String day_wind_comp;
    private String night_wind;
    private String night_wind_comp;
    private String day_weather_id;
    private String night_weather_id;

    public String getCity_id() {
        return city_id;
    }

    public void setCity_id(String city_id) {
        this.city_id = city_id;
    }

    public String getCity_name() {
        return city_name;
    }

    public void setCity_name(String city_name) {
        this.city_name = city_name;
    }

    public String getWeather_date() {
        return weather_date;
    }

    public void setWeather_date(String weather_date) {
        this.weather_date = weather_date;
    }

    public String getDay_weather() {
        return day_weather;
    }

    public void setDay_weather(String day_weather) {
        this.day_weather = day_weather;
    }

    public String getNight_weather() {
        return night_weather;
    }

    public void setNight_weather(String night_weather) {
        this.night_weather = night_weather;
    }

    public String getDay_temp() {
        return day_temp;
    }

    public void setDay_temp(String day_temp) {
        this.day_temp = day_temp;
    }

    public String getNight_temp() {
        return night_temp;
    }

    public void setNight_temp(String night_temp) {
        this.night_temp = night_temp;
    }

    public String getDay_wind() {
        return day_wind;
    }

    public void setDay_wind(String day_wind) {
        this.day_wind = day_wind;
    }

    public String getDay_wind_comp() {
        return day_wind_comp;
    }

    public void setDay_wind_comp(String day_wind_comp) {
        this.day_wind_comp = day_wind_comp;
    }

    public String getNight_wind() {
        return night_wind;
    }

    public void setNight_wind(String night_wind) {
        this.night_wind = night_wind;
    }

    public String getNight_wind_comp() {
        return night_wind_comp;
    }

    public void setNight_wind_comp(String night_wind_comp) {
        this.night_wind_comp = night_wind_comp;
    }

    public String getDay_weather_id() {
        return day_weather_id;
    }

    public void setDay_weather_id(String day_weather_id) {
        this.day_weather_id = day_weather_id;
    }

    public String getNight_weather_id() {
        return night_weather_id;
    }

    public void setNight_weather_id(String night_weather_id) {
        this.night_weather_id = night_weather_id;
    }

}

5.请求数据,创建retrofit工具类RetrofiClient,使用单例模式,方便在activity中调用

public class RetrofitClient {

    private static Retrofit retrofit;

    /**
     * 创建Retrofit对象
     * @return
     */
    public static Retrofit getRetrofit() {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(HttpUtils.BaseUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(client())
                    .build();
        }
        return retrofit;
    }

 	/**
     * okhttp过滤器
     * @return
     */
    public static OkHttpClient client(){
        OkHttpClient client = new OkHttpClient.Builder()//okhttp设置部分,此处还可再设置网络参数
                .addInterceptor(logInterceptor())//添加日志拦截
                .build();
        return client;
    }
    /**
     * 打印log日志
     * @return
     */
    public static HttpLoggingInterceptor logInterceptor(){
        return new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                //打印retrofit日志
                Log.e("RetrofitLog", "retrofitBack = " + message);
            }
        }).setLevel(HttpLoggingInterceptor.Level.BODY);//设置打印数据的级别
    }
}

这里的baseUrl是"http://v.juhe.cn/historyWeather/"可直接写
在这里呢,新建了一个放地址的类

public class HttpUtils {
    public static String BaseUrl = "http://v.juhe.cn/historyWeather/";
}

}

6.处理Exception

public class ExceptionHandle {
    private static final int UNAUTHORIZED = 401;
    private static final int FORBIDDEN = 403;
    private static final int NOT_FOUND = 404;
    private static final int REQUEST_TIMEOUT = 408;
    private static final int INTERNAL_SERVER_ERROR = 500;
    private static final int BAD_GATEWAY = 502;
    private static final int SERVICE_UNAVAILABLE = 503;
    private static final int GATEWAY_TIMEOUT = 504;

    public static ResponeThrowable handleException(Throwable e) {
        ResponeThrowable ex;
        Log.i("tag", "e.toString = " + e.toString());
        if (e instanceof HttpException) {
            HttpException httpException = (HttpException) e;
            ex = new ResponeThrowable(e, ERROR.HTTP_ERROR);
            switch (httpException.code()) {
                case UNAUTHORIZED:
                case FORBIDDEN:
                case NOT_FOUND:
                case REQUEST_TIMEOUT:
                case GATEWAY_TIMEOUT:
                case INTERNAL_SERVER_ERROR:
                case BAD_GATEWAY:
                case SERVICE_UNAVAILABLE:
                default:
                    //ex.code = httpException.code();
                    ex.message = "网络错误";
                    break;
            }
            return ex;
        } else if (e instanceof ServerException) {
            ServerException resultException = (ServerException) e;
            ex = new ResponeThrowable(resultException, resultException.code);
            ex.message = resultException.message;
            return ex;
        } else if (e instanceof JsonParseException
                || e instanceof JSONException
            /*|| e instanceof ParseException*/) {
            ex = new ResponeThrowable(e, ERROR.PARSE_ERROR);
            ex.message = "解析错误";
            return ex;
        } else if (e instanceof ConnectException) {
            ex = new ResponeThrowable(e, ERROR.NETWORD_ERROR);
            ex.message = "连接失败";
            return ex;
        } else if (e instanceof javax.net.ssl.SSLHandshakeException) {
            ex = new ResponeThrowable(e, ERROR.SSL_ERROR);
            ex.message = "证书验证失败";
            return ex;
        } else {
            ex = new ResponeThrowable(e, ERROR.UNKNOWN);
            ex.message = "未知错误";
            return ex;
        }
    }

    /**
     * 约定异常
     */
    class ERROR {
        /**
         * 未知错误
         */
        public static final int UNKNOWN = 1000;
        /**
         * 解析错误
         */
        public static final int PARSE_ERROR = 1001;
        /**
         * 网络错误
         */
        public static final int NETWORD_ERROR = 1002;
        /**
         * 协议出错
         */
        public static final int HTTP_ERROR = 1003;

        /**
         * 证书出错
         */
        public static final int SSL_ERROR = 1005;
    }

    public static class ResponeThrowable extends Exception {
        public int code;
        public String message;

        public ResponeThrowable(Throwable throwable, int code) {
            super(throwable);
            this.code = code;
        }
    }

    /**
     * ServerException发生后,将自动转换为ResponeThrowable返回
     */
    public static class ServerException extends RuntimeException {
        public int code;
        public String message;

        public ServerException(int code, String message) {
            this.code = code;
            this.message = message;
        }
    }

}

7.自定义subscriber接收 的数据并处理Exception

继承Rxjava的DefaultSubscriber类HttpSubscriber

  • 由于在ApiService中使用的是Flowable所以这里对应的是Subscriber,如果用Observable所对应的就是Observer
public abstract class HttpSubscriber<T> extends DefaultSubscriber<HttpResult<T>> {

    @Override
    public void onNext(HttpResult<T> tHttpResult) {
    
        if (tHttpResult.getError_code()==0){
            Log.e("errorcode==",tHttpResult.getError_code()+"");
            //成功 把数据传递给SubScriber的onNext
            myNext(tHttpResult.getResults());
        }else{
        	//失败无数据把错误code和msg向下传递
            myerror(ExceptionHandle.handleException(new ExceptionHandle.ServerException(tHttpResult.getError_code(),tHttpResult.getReason())));
    	}
      
    }

    @Override
    public void onError(Throwable t) {
        myerror(ExceptionHandle.handleException(t));
    }

    @Override
    public void onComplete() {

    }

    //成功
    public abstract void myNext(T t);

    /**
     * 失败
     */
    public abstract void myerror(ExceptionHandle.ResponeThrowable responeThrowable);

}

8.最后在activity的请求

 RetrofitClient.getRetrofit().create(ApiService.class)
                .getHistroy("1b3186d6b6f79395ff8bd299e6012a10", "1157", "2017-11-29")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new HttpSubscriber<HistroyResult>() {
                    @Override
                    public void myNext(HistroyResult histroyResult) {
                        dayTemp.setText(histroyResult.getCity_name());
                        //在这里就可以进行UI操作了set值等
                    }

                    @Override
                    public void myerror(ExceptionHandle.ResponeThrowable responeThrowable) {
                        Log.e("activity", responeThrowable.code + ""+responeThrowable.message);

                    }
                });

上面的.getHistroy中请求的三个参数,第一个是聚合的key可以改成自己的就可以了

到此封装完成,就可以成功请求数据了。
以后会慢慢完善。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值