基于Retrofit2.0实现
资源准备 导包:
首先我们需要在gradle文件中引入这两个包//版本要一致
compile 'com.android.support:appcompat-v7:23.2.0'
compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.jakewharton:butterknife:7.0.1'
首先: 使用时要定义一个接口来返回我们数据
public interface RequestData {
// @FormUrlEncoded
// @POST("{url}")
// Observable<Object> query(@Path("url") String url, @FieldMap Map<String, Object> params);
//键值对传输参数
//API接口比较多时会拆分最后两个地址
@FormUrlEncoded
@POST("{url1}/{url2}")
Observable<Object> query(@Path("url1")String url1,@Path("url2") String url2,@FieldMap Map<String, Object> params);
//传输一个url
@Headers({"Content-Type: application/json","Accept: application/json"})
@POST("register")
Observable<Object> queryto(@Body RequestBody body );
}
query方法是参数传输形式为键值对并且最后需要拼接的url为两个时候,queryto方法是参数传输形式对象时并且拼接一个url时
注解详解 @POST代表请求方式为post请求@GET为get请求在这里不做解释
这两个方法@POST里面的内容可以很明显看出来,里面内容需要请求的地址,也就是说这个字符串会拼接在我 们根路径之后,因为在项目中肯定会有很多的api这时候需要动态拼接Url所以就需要 query方法了“{url1}”位站位,在我们调用query方法时@Path("url1")String url1传过来的url1的值会替换@POST里面的{url1}
Observable<Object> 为集成RxJava做准备可以先不用注意如果不需要集成RxJava可以去掉。
第二步就要创建Retrofit对象来发起网络请求
private static Retrofit getRetrofit(String url) {
long SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MiB 缓存容量
String cacheFile = BaseApplication.getContextObject().getCacheDir()+"/http";
Cache cache = new Cache(new File(cacheFile), SIZE_OF_CACHE);
OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(CachingControlInterceptor.REWRITE_RESPONSE_INTERCEPTOR)
.addInterceptor(CachingControlInterceptor.REWRITE_RESPONSE_INTERCEPTOR_OFFLINE)
.cache(cache)
.build();
return new Retrofit.Builder().baseUrl(url)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
调用此方法并且利用得到的对象 调用.create()方法获取一个RequestData接口对象
public static RequestData getRequest(){
return getRetrofit(Url).create(RequestData.class);
};
封装此方法生成对象这里传输的Url参数:http://192.168.1.10:8880/booking-api/ 加上我们接口里面的字符串就获得了完整的请求路径。
最终调用:参数封装在body对象中
如果不使用RxJava:直接获取请求结果
JSONObject json = new JSONObject();
json.put("head", new JSONObject(head));
json.put("con", new JSONObject(con));
RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), json.toJSONString());
Call<String> call = (Call<String>) HttpUtil.getRequest().queryto(body);
call.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
Log.e("===","return:"+response.body().toString());
}
@Override
public void onFailure(Call<String> call, Throwable t) {
Log.e("===","失败");
}
});
我们可以看到如果不继承RxJava调用call.enque方法就结束。
重点是集成RxJava的,看不懂此处代码的可以先看下面方法解释
JSONObject json = new JSONObject();
json.put("head", new JSONObject(head));
json.put("con", new JSONObject(con));
RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), json.toJSONString());
HttpUtil.getRequest().queryto(body).compose(new RxHelper<Object>().io_main(MainActivity.this))
.subscribe(new RxSubscriber<Object>() {
@Override
public void _onNext(Object object) {
MYToast.show("chenggong" + object.toString());
Log.e("Tag", object.toString());
}
@Override
public void _onError(String msg) {
MYToast.show("shibai" + msg);
}
});
首先我们要了解RxJava不了解可以先看下RxJava
RxJava是一种观察设计这模式:
第一步我们定义的RequestData接口里面的方法用Observable(被观察者)
那么我们就需要有观察者Observer ,在RxJava中内置了Subscriber实现了Observer的抽象类。
自定义RxSubscriber集成Subscriber
public abstract class RxSubscriber<T> extends Subscriber<T> {
@Override
public void onCompleted() {
Log.e("Tag","onCompleted");
// ProgressDialogUtil.dismiss();
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
Log.e("Tag","getMessage"+e.getMessage());
_onError(e.getMessage());
// ProgressDialogUtil.dismiss();
if (!NetUtils.isConnected(BaseApplication.getContextObject())) {
MYToast.show("请求失败,请检查网络!");
return;
}
}
@Override
public void onNext(T t) {
_onNext(t);
}
public abstract void _onNext(T t);
public abstract void _onError(String msg);
}
下面就是将我们观察者和被观察者联系起来
我们通过HttpUtil.getRequest().queryto(body)得到了被观察者。通过 subscribe()方法将它和观察者RxSubscriber联系起来。
这样我们整个流程请求就串起来了。
还有一个方法我们并没有说到那就是.compose()是对Observable进行整体转换。需要先定义Rxhelper类
public class RxHelper<T> {
//子线程运行,主线程回调
public Observable.Transformer<T, T> io_main(final BaseActivity context) {
return new Observable.Transformer<T, T>() {
@Override
public Observable<T> call(Observable<T> tObservable) {
Observable<T> tObservable1 = (Observable<T>) tObservable
.subscribeOn(Schedulers.io())
.doOnSubscribe(new Action0() {
@Override
public void call() {
// ProgressDialogUtil.showProgress(context, "正在加载,请稍候");
}
})
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.compose(RxLifecycle.bindUntilEvent(context.lifecycle(), ActivityEvent.STOP));
return tObservable1;
}
};
}
}
RxHelper中context.lifecycle()为获取一个Observable对象
lifecycle()我们写在BaseActivity中方便
public final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();
@NonNull
@Override
public Observable<ActivityEvent> lifecycle() {
return lifecycleSubject.asObservable();
}
第二种使用:
参数为键值对传输,并且拼接URl为两个
map.put("body",jsonObject.toJSONString());
map.put("appid","0fbf8729dfc96b0280843ea934298");
map.put("timeStamp",timecurrentTimeMillis+"");
map.put("character",character);
map.put("sign",md5sign);
map.put("askToken",askToken);
HttpUtil.getRequest().query("enterprise","login",map).compose(newRxHelper<Object().io_main(MainActivity.this))
.subscribe(new RxSubscriber<Object>() {
@Override
public void _onNext(Object object) {
MYToast.show("chenggong"+object.toString());
Log.e("Tag",object.toString());
}
@Override
public void _onError(String msg) {
MYToast.show("shibai"+msg); }
});