Android Retrofit 2.0使用
實例帶你了解Retrofit 2.0的使用,分享目前開發Retrofit遇到的坑和心得。
添加依賴
app/build.gradle
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
聲明接口
/**
* Call<T> get();必須是這種形式,這是2.0之后的新形式
* 如果不需要轉換成Json數據,可以用了ResponseBody;
* 你也可以使用Call<GsonBean> get();這樣的話,需要添加Gson轉換器
*/
public interface ApiStores {
@GET("adat/sk/{cityId}.html")
Call<ResponseBody> getWeather(@Path("cityId") String cityId);
}
如果鏈接是 http://ip.taobao.com/service/getIpInfo.php?ip=202.202.33.33
@GET("http://ip.taobao.com/service/getIpInfo.php")
Call<ResponseBody> getWeather(@Query("ip") String ip);
接口調用
Retrofit retrofit = new Retrofit.Builder()
//這里建議:- Base URL: 總是以/結尾;- @Url: 不要以/開頭
.baseUrl("http://www.weather.com.cn/")
.build();
ApiStores apiStores = retrofit.create(ApiStores.class);
Call<ResponseBody> call = apiStores.getWeather("101010100");
如果@GET(" http://ip.taobao.com/service/getIpInfo.php"),則baseUrl無效。
注意這個任務是網絡任務,不要忘記給程序加入網絡權限
<uses-permission android:name="android.permission.INTERNET" />
同步調用
try {
Response<ResponseBody> bodyResponse = call.execute();
String body = bodyResponse.body().string();//獲取返回體的字符串
Log.i("wxl", "body=" + body);
} catch (IOException e) {
e.printStackTrace();
}
同步需要處理android.os.NetworkOnMainThreadException
異步調用
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Response<ResponseBody> response) {
try {
Log.i("wxl", "response=" + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Throwable t) {
Log.i("wxl", "onFailure=" + t.getMessage());
}
});
移除請求
call.cancel();
JSON解析庫
Retrofit 2現在支持許多種解析方式來解析響應數據,包括Moshi,一個由Square創建的高效JSON解析庫。
添加gson依賴
app/build.gradle
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'
jsonschema2pojo
訪問 jsonschema2pojo ,自動生成Java對象,如果你對gson還不熟悉,筆者建議你手動生成Java對象,感受下。
這里如果選擇Gson,生成的代碼中存在@Generated注解,Android默認并沒有javax.annotation library。如果你希望保留@Generated注解,需要添加如下的依賴。
compile 'org.glassfish:javax.annotation:10.0-b28'
或者,你可以直接刪除這個注解,完全沒有問題。筆者當然不會加這個依賴啦。
Gsonformat
作用:Android studio插件,一般接口返回數據后要建立自己的bean,Gsonformat幫助你快速生成,不用一條一條去寫。比jsonschema2pojo更加簡單。
安裝步驟:Android studio-Settings-Plugins-搜Gsonformat-Install Plugin
效果預覽:
實例代碼
依舊演示上面的天氣: http://www.weather.com.cn/adat/sk/101010100.html
public class WeatherJson {
//weatherinfo需要對應json數據的名稱,我之前隨便寫了個,被坑很久
private Weatherinfo weatherinfo;
public Weatherinfo getWeatherinfo() {
return weatherinfo;
}
public void setWeatherinfo(Weatherinfo weatherinfo) {
this.weatherinfo = weatherinfo;
}
//city、cityid必須對應json數據的名稱,不然解析不了
public class Weatherinfo {
private String city;
private String cityid;
private String temp;
private String WD;
private String WS;
private String SD;
private String WSE;
private String time;
private String isRadar;
private String Radar;
private String njd;
private String qy;
//這里省略get和set方法
}
}
ApiStores:
public class AppClient {
static Retrofit mRetrofit;
public static Retrofit retrofit() {
if (mRetrofit == null) {
mRetrofit = new Retrofit.Builder()
.baseUrl("http://www.weather.com.cn/")
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return mRetrofit;
}
public interface ApiStores {
@GET("adat/sk/{cityId}.html")
Call<WeatherJson> getWeather(@Path("cityId") String cityId);
}
}
調用:
private void getWeather() {
AppClient.ApiStores apiStores = AppClient.retrofit().create(AppClient.ApiStores.class);
Call<WeatherJson> call = apiStores.getWeather("101010100");
call.enqueue(new Callback<WeatherJson>() {
@Override
public void onResponse(Response<WeatherJson> response) {
Log.i("wxl", "getWeatherinfo=" + response.body().getWeatherinfo().getCity());
}
@Override
public void onFailure(Throwable t) {
}
});
}
經Gson轉換器, Call<ResponseBody> 換成自己要寫的 Call<WeatherJson>
RxJava
依賴以下:
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta3'
compile 'io.reactivex:rxandroid:1.0.1'
增加addCallAdapterFactory
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.nuuneoi.com/base/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
ApiStores
@GET("adat/sk/{cityId}.html")
Observable<WeatherJson> getWeatherRxjava(@Path("cityId") String cityId);
subscribe部分的代碼在Schedulers.io被調用,需要把observeOn(AndroidSchedulers.mainThread())添加到鏈表中。
private void getWeatherRxjava() {
AppClient.ApiStores apiStores = AppClient.retrofit().create(AppClient.ApiStores.class);
Observable<WeatherJson> observable = apiStores.getWeatherRxjava("101010100");
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<WeatherJson>() {
@Override
public void onCompleted() {
Log.i("wxl", "onCompleted");
}
@Override
public void onError(Throwable e) {
Log.i("wxl", "e=" + e.getMessage());
}
@Override
public void onNext(WeatherJson weatherJson) {
Log.i("wxl", "getWeatherinfo=" + weatherJson.getWeatherinfo().getCity());
}
});
}
來自: http://www.jianshu.com/p/c213d9ec6c9b