RxJava和Retrofit的简单使用
Posted wlwqnj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RxJava和Retrofit的简单使用相关的知识,希望对你有一定的参考价值。
在最近做的项目中,因为频繁用到网络请求,所以使用了现在比较流行的框架RxJava和Retrofit来代替之前的Okhttp的繁琐请求。
retrofit是用来做网络请求操作,RxJava是用来切换线程、转换数据操作的。
首先第一步,使用三方的框架,肯定是先添加依赖包。项目中用的Rxjava2.0、retrofit2.0,而且Rxjava2.0和Rxjava1.0并不兼容,所以使用起来需要注意。添加一下依赖。
compile "com.squareup.retrofit2:retrofit:$rootProject.versions.libRetrofit"
compile "com.squareup.retrofit2:converter-gson:$rootProject.versions.libRetrofit"
compile "com.squareup.retrofit2:adapter-rxjava2:$rootProject.versions.libRetrofit"
compile "com.squareup.okhttp3:okhttp:$rootProject.versions.libOkhttp"
compile "com.squareup.okhttp3:logging-interceptor:$rootProject.versions.libOkhttp"
compile "io.reactivex.rxjava2:rxjava:$rootProject.versions.libRxJava"
compile "io.reactivex.rxjava2:rxandroid:$rootProject.versions.libRxAndroid"
第二步,创建一个Api实例 用来获取接口的请求对象 在init()方法中通过baseUrl或得到Retrofit对象, 请求方法等都是放在接口中,接口与retrofit关联在getNetDemo()方法中实现。
public class NetDemoApi {
private static NetDemoApi nInstance = new NetDemoApi();
private Retrofit mRequestDemo;
//baseUrl是每一个网络请求的前段,但必须是以 “/”结尾
private String mRequestDemoBaseUrl = "www.baidu.com/";
public static NetDemoApi getInstance(){
return nInstance;
}
private NetDemoApi(){
init();
}
private void init() {
//这一步就把baseurl和Retrofit关联了起来,生成Retrofit对象
mRequestDemo = configure(mRequestDemoBaseUrl);
}
private NetDemo getNetDemo(){
return mRequestDemo.create(NetDemo.class);
}
//配置retrofit
private Retrofit configure(String baseUrl){
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
WLog.i(message);
}
});
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder builder = new OkHttpClient.Builder();
//这只网络请求的拦截器 如果需要获取到响应头等相应信息,在此处就可以获得 如果不需要可以不写
builder.networkInterceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
Headers headers = response.headers();
List<String> cookies = headers.values("Set-Cookie");
Session session = Session.getInstance();
session.setCookies(Utils.getCookie(cookies));
Log.d(getClass().getSimpleName(),"设置cookie " + session.getCookies());
return response;
}
});
builder.addInterceptor(logging);
builder.connectTimeout(30, TimeUnit.SECONDS);
builder.readTimeout(40, TimeUnit.SECONDS);
OkHttpClient client = builder.build();
return new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
//这是rxjava的转换器,这个是rxjava2的默认适配器工厂,如果我们需要转换成bean,可以添加gson的转换器,直接添加就可以,需要添加依赖包
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
}
第三步,写实现的接口,这个接口中,才是我们需要请求的路径 如下 @get 就是一个get请求的方法, @post就是一个post请求
@url 是直接传入一个已知的URl进去,直接请求Url,而且跟baseUrl无关,不会跟baseUrl进行拼接;
@Query 就是在URl后面进行键值对的拼接,如下 tip传入1 ,就会把 tip=1 拼接到loginicon=true的后面,get和post请求都是这样拼接。
@Path 就是把传入的字符串直接传入注解中{uuid}中的位置处;
@body 是post请求时,传入的requestBody对象;
@Header 可以给网络请求添加请求头信息,添加Cookie就写cookie,@Header("Cookie") String cookie,
以上传入的url参数都会和baseUrl进行拼接,得到一个完整的Url去进行网络请求(除了@url)。
返回的就是Observable对象,我们调用此方法后,获得observable对象,接下来用Rxjava进行数据解析,筛选。
public interface NetDemo {
@GET
Observable<ResponseBody> requestDemo(@url String url);
@GET("cgi-bin/mmwebwx-bin/login?loginicon=true")
Observable<ResponseBody> requestScanResult(@Query("tip") int tip,
@Query("uuid") String uuid,
@Query("r") String r,
@Query("_") String p);
@POST("qrcode/{uuid}")
Observable<ResponseBody> requestGenQRCode(@Path("uuid") String uuid,
@Body RequestBody body);
@POST("cgi-bin/mmwebwx-bin/webwxstatusnotify?lang=zh_CN")
public Observable<ResponseBody> webwxstatusnotify(@Query("pass_ticket") String passTicket,
@Header("Cookie") String cookie,
@Body RequestBody body);
}
第四步,在代码中进行网络请求,
Observable<ResponseBody> observable = WeChatNetApi.getInstance().getLoginInfo().requestLoginInfo(url); //返回Observable对象
observable.subscribeOn(Schedulers.io()) //进行网络请求是在那个线程 io 就是在子线程
.map(new Function<ResponseBody, Bitmap>() { //可以通过map进行转换,把结果转换为一个我们需要使用的类型(如demo,返回一个bitmap类型)
@Override
public Bitmap apply(@io.reactivex.annotations.NonNull
ResponseBody responseBody) {
return BitmapFactory.decodeStream(responseBody.byteStream());
}
})
.flatMap(new Function<String, ObservableSource<Bitmap>>() { //还可以通过flatMap转化为Observable对象,转换为Observable对象后,还可以继续进行转换操作,直到我们需要的类型
@Override
public ObservableSource<Bitmap> apply(
@io.reactivex.annotations.NonNull String uuid) {
return genQRCode(uuid);
}
}
.filter(new Func1<Community, Boolean>() { //只有返回true,才会继续向下走,如果返回是false,就不会继续向下走
@Override
public Boolean call(Community community) {
return community.houses.size()>10;
}
})
.observeOn(AndroidSchedulers.mainThread()) //网络请求结束,切换回主线程,进行数据处理,或者显示的操作
.subscribe(new Observer<ResponseBody>() { //转换结束,得到了我们需要的数据,进行显示,先切换到主线程
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(ResponseBody body) { //订阅后subscribe会执行的方法
messageActivity.returnTextInfo(asJsonObject, l);
}
@Override
public void onError(Throwable e) { //如果流程中有报错,会走到此
}
@Override
public void onComplete() { //onNext之后,如果还有后续的动作,可以在此继续,onnext后会调用complete;
}
});
.doOnNext(new Consumer<ResponseBody>() { //doOnNext 直接订阅是一个偷懒的写法,这样写代码比较简洁,而且这一步操作完之后,我也不需要继续任何操作
@Override
public void accept(@io.reactivex.annotations.NonNull ResponseBody body) throws Exception {
handleLoginInfoResponse(url,body);
}
}).subscribe();
以上是关于RxJava和Retrofit的简单使用的主要内容,如果未能解决你的问题,请参考以下文章
如何在Activity中使用Retrofit和RxJava / RxAndroid处理旋转?
retrofit2+rxjava+mockserver使用和理解
retrofit2+rxjava+mockserver使用和理解