Android 开源项目学习之Retrofit2.0使用篇
- 引入Retrofit 相关的库
compile 'io.reactivex:rxjava:1.1.0' //RxJava 相关
compile 'io.reactivex:rxandroid:1.1.0' //RxJava 相关
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4' //Retrofit Rxjava Adapter
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4' //Retrofit
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4' //Gson Adapter
compile 'com.google.code.gson:gson:2.6.2' //Gson - 定义 Api 接口
一个Service是一个接口如下所示,它一般指定了http方式是一个get还是post方式,以及一个相对的路径。public interface OpenWeatherApi {
@GET("weather")
Call<WeatherResult> getCityWeather(@Query("id") String id,@Query("appid") String ApiId);
} - 使用注释来创建url
这个方面请大家看下这篇博客,个人认为总结得十分全面,所以就直接转过来了:
http://blog.csdn.net/stven_king/article/details/52372172
最常使用的请求方式:
@GET @POST
请求url相关的注释:
@Query,@QueryMap,@Field,@FieldMap,@FormUrlEncoded,@Path,@Url
( 1 ) GET 请求方式:
public interface GitHubService {//无参数@GET("users/stven0king/repos") |
( 2 ) POST 请求方式:
public interface GitHubService {//无参数@POST("users/stven0king/repos") |
@POST @GET多了一个@FromUrlEncoded的注解。如果去掉@FromUrlEncoded在post请求中使用@Field和@FieldMap,那么程序会抛出Java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1)的错误异常。
( 3 ) 半静态的url 地址请求:
public interface GitHubService {@GET("users/{user}/repos") |
( 4 ) 动态的url地址请求:
public interface GitHubService {@GET |
- 创建retrofit对象在Retrofit 2.0中,需要我们自己引入Converter 不然的话Retrofit 只能接收字符串结果,下面是retrofit 支持的json converter
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.openweathermap.org/data/2.5/")
.addConverterFactory(GsonConverterFactory.create())
.build();Gson: com.squareup.retrofit:converter-gson
Jackson: com.squareup.retrofit:converter-jackson
Moshi: com.squareup.retrofit:converter-moshi
Protobuf: com.squareup.retrofit:converter-protobuf
Wire: com.squareup.retrofit:converter-wire
Simple XML: com.squareup.retrofit:converter-simplexml - 使用retrofit对象来创建对应的API接口:5.使用上面创建的API接口来访问对应的服务:
OpenWeatherApi mWeatherService = retrofit.create(OpenWeatherApi.class);
(这里为了安全所以我这边用了一个伪appid,大家可以自己申请然后替换)Call<WeatherResult> resultCall = mWeatherService.getCityWeather("1790437","f8ddddd63c40c0bcb89");
resultCall.enqueue(new Callback<WeatherResult>() {
@Override
public void onResponse(Call<WeatherResult> call, Response<WeatherResult> response) {
if(response.body() == null) {
Log.i("xiaohai.lin","Request Failed Response Code = "+ response.code());
return;
}
Log.i("xiaohai.lin","Templete = "+response.body().getMain().getTemp());
Log.i("xiaohai.lin","getDescription = "+response.body().getWeather().get(0).getDescription());
}
@Override
public void onFailure(Call<WeatherResult> call, Throwable t) {}
}); - 异步请求以上代码发起了一个在后台线程的请求并从response 的response.body()方法中获取一个结果对象。这里onResponse和onFailure方法是在主线程中调用的。
resultCall.enqueue(new Callback<WeatherResult>() {
@Override
public void onResponse(Call<WeatherResult> call, Response<WeatherResult> response) {
if(response.body() == null) {
Log.i("xiaohai.lin","Request Failed Response Code = "+ response.code());
return;
}
Log.i("xiaohai.lin","Templete = "+response.body().getMain().getTemp());
Log.i("xiaohai.lin","getDescription = "+response.body().getWeather().get(0).getDescription());
}
@Override
public void onFailure(Call<WeatherResult> call, Throwable t) {}
}); - 同步请求
同步请求需要调用execute方法,但是由于同步方式会阻塞线程所以不能在主线程中调用。否则会遇到NetworkOnMainThreadException异常。8 取消正在进行中访问new AsyncTask<String, Integer, Response<WeatherResult>>(){
@Override
protected Response<WeatherResult> doInBackground(String... params) {
if(params == null|| params[0] == null||params[1]== null) {
return null;
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.openweathermap.org/data/2.5/")
.addConverterFactory(GsonConverterFactory.create())
.build();
OpenWeatherApi mWeatherService = retrofit.create(OpenWeatherApi.class);
final Call<WeatherResult> resultCall = mWeatherService.getCityWeather(params[0],params[1]);
Response<WeatherResult> result = null;
try {
result = resultCall.execute();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
@Override
protected void onPostExecute(Response<WeatherResult> response) {
if(response == null || response.body() == null) {
return;
}
Log.i("xiaohai.lin","Templete = "+response.body().getMain().getTemp());
Log.i("xiaohai.lin","getDescription = "+response.body().getWeather().get(0).getDescription());
}
}.execute("1790437","f8ddddcb89");9 获取结果的处理call.cancel();
在Retrofit 1.9中,如果获取的 response 不能被解析成定义好的对象,则会调用failure。但是在Retrofit 2.0中,不管 response 是否能被解析。onResponse总是会被调用。但是在结果不能被解析的情况下,response.body()会返回null。
如果response存在什么问题,onResponse也会被调用。我们可以从response.errorBody().string()中获取错误信息的主体。
10 Retrofix 结合 Rxjava
public interface OpenWeatherApis { |
Retrofit retrofit = new Retrofit.Builder() |
OpenWeatherApis openWeatherApis = retrofit.create(OpenWeatherApis.class); |
11 添加log支持
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(); |
11 Retrofix 结合 Realm:
Realm 是我个人的喜好,是用得最爽的一个nosql类型的数据库,没有之一。
Realm 可以与 Retrofit 1.x 和 2.x 无缝配合工作。但注意 Retrofit 不会自动将对象存入 Realm。
需要通过调用 Realm.copyToRealm() 或 Realm.copyToRealmOrUpdate() 来将它们存入 Realm。
realm.beginTransaction(); |