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可以改成自己的就可以了
到此封装完成,就可以成功请求数据了。
以后会慢慢完善。