为了填补上篇博客立的flag,最近也是学习了一下Retrofit以及和Rxjava的联合使用,下面就我遇到的一些困难来跟大家共同探讨一下,同时自己也再梳理一遍。先来从Retrofit说起吧。
在我看来,Retrofit就是将网页上的api接口转化为能在java中调用的接口,所以呢与一般的库的使用也不太一样,需要注册对应的interface,将java和web联系起来,然后借助Rxjava来处理web返回的消息。接下来就来看一下它简单的使用。
compile 'com.squareup.retrofit2:retrofit:2.1.0'
首先要添加依赖,版本号可以去github看看使用最新的版本。下面就来看一下具体的使用吧,为了避免混淆,先讲不使用Rxjava的。
一、创建实例
Retrofit weatherTry=new Retrofit
.Builder() .baseUrl("http://apis.baidu.com/heweather/weather/free/")
.client(new OkHttpClient())
.build();
这里就是在百度api上随便找的一个http://apistore.baidu.com/apiworks/servicedetail/478.html 可以点进去看一下具体的要求。Retrofit2 的baseUlr 必须以 /(斜线) 结束,不然会抛出一个IllegalArgumentException,所以如果你看到别的教程没有以 / 结束,那么多半是直接从Retrofit 1.X 照搬过来的。这就是一个固定的格式也没什么好多说的。
二、接下来就是接口定义了。首先看一下几种请求的方法
平时主要用到的也就是Get和Post,其它的了解一下就可以了。然后看一下在请求之中要是用的具体的参数:
这里就要根据对应的字段,来使用对应的参数,这就要在实践中自己来摸索了。
public interface WeatherApi {
@GET("?city=beijing")
Call<ResponseBody> getWeather(@Header("apikey") String key);
}
在api的接口要求中可以看到要求上传一个apikey的,而且是header类型的,所以这里就@Header(“apikey”),括号里面的内容都要看api的具体情况不是自己定义的。后面的String则是根据需要可以自由变换或者是自定义。下面说一下@Get中的地址拼接问题。
从上面不能难看出以下规则:
1.如果你在注解中提供的url是完整的url,则url将作为请求的url。
2.如果你在注解中提供的url是不完整的url,且不以 / 开头,则请求的url为baseUrl+注解中提供的值
3.如果你在注解中提供的url是不完整的url,且以 / 开头,则请求的url为baseUrl的主机部分+注解中提供的值
所以我们上面拼接出来的地址就是http://apis.baidu.com/heweather/weather/free?city=beijing
接口也有了,实例也有了,接下来:
三、获取api对象
WeatherApi weatherApi=weatherTry.create(WeatherApi.class);
其实呢就是将我们定义的接口和实例连接了起来,也是固定的格式。
四、获取请求对象
还记得上面的interface中有个getWeather么,那就是我们的具体的请求方法,第四步就是来调用这个方法了。
final Call<ResponseBody> call=weatherApi.getWeather("a79124c4594c2e5a0799a39ea8f64c87");
这样利用一个Call类型,就完成了对请求方法的具体定义,ResponseBody是Retrofit中的默认返回类型。
五、发送请求
该定义的也都定义的,接下来就要发送请求了。我这里用的是异步执行。
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.e("onResponse", "response=" + response.body().string());
}catch (IOException e){
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable throwable) {
}
});
这样就发送了请求,而且在Log中打印了返回结果。
就这样完成了请求的发送以及接收数据。但这样就结束了么?这些数据是我们想要的格式么?说好的Rxjava去哪了?我们接着看。下面我们就来重新走一遍流程,当然是用Rxjava了。
Retrofit zhuangRetrofit=new Retrofit.Builder()
.client(new OkHttpClient())
.baseUrl("http://www.zhuangbi.info/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
还是先创建实例
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
不一样的是这里多了 两个add。这就是为了要再Rxjava中转换json的格式要添加的格式工厂了。先来看一下这个接口的返回数据的类型:
我们决定来解析出来内容中的description字段和image_url字段。所以需要先自定义一个类
package com.sp.rerofittry;
public class ZhuangbiImage {
public String description;
public String image_url;
public String file_size;
public Upload upload;
}
class Upload{
String id;
String name;
String description;
String disk;
String path;
String size;
String user_id;
String created_at;
String updated_at;
String uploadable_id;
String uploadable_type;
String url;
}
然后看一下接口的创建。
public interface ZhuangbiApi {
@GET("search")
Observable<List<ZhuangbiImage>> search(@Query("q") String query);
}
这里的Observable就是Rxjava的使用了,这里充当的就是被观察者的角色,后面会在Activity中创建观察者,然后订阅,就完成了之间的交互。
final ZhuangbiApi zhuangbiApi=zhuangRetrofit.create(ZhuangbiApi.class);
zhuangbiApi .search("110")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<ZhuangbiImage>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onNext(List<ZhuangbiImage> zhuangbiImages) {
for (int i=0;i<zhuangbiImages.size();i++){
Log.e("list",zhuangbiImages.get(i).image_url+" "+zhuangbiImages.get(i).description);
Log.e("name",zhuangbiImages.get(i).upload.created_at);
}
}
});
要注意的是
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
这里在io线程中订阅然后在主线程中返回结果,耗时的工作都不能放在主线程来实现。然后看一下返回结果
就解析出了我们想要的部分。图片的url以及标题。这就是Retrofit和Rxjava的简单结合了。更多内容…敬请期待…
另外放出这个demo的github地址 https://github.com/CallMeSp/Retrofit-Rxjava_demo.git