
作為目前Android最流行的Http Client框架之一,retrofit的學(xué)習(xí)已是大勢所趨。
學(xué)習(xí)于:
http://www.itdecent.cn/p/308f3c54abdd
http://blog.csdn.net/sk719887916/article/details/51755427
以下代碼示例是retrofit的原始形態(tài),分為兩部分:
一是定義一個接口,其中@GET("api/public")表示請求方式和請求的路徑;@Query("uid") String uid表示需要傳入String類型的參數(shù),對應(yīng)的參數(shù)名是"uid";泛型代表著HTTP響應(yīng)體轉(zhuǎn)換的類型,此時是ResponseBody。
public interface ApiService {
@GET("api/public")
Call<ResponseBody> getData(@Query("uid") String uid);
}
二是創(chuàng)建retrofit實例,baseUrl表示請求的域名,同上述請求路徑,參數(shù)組成完整的網(wǎng)址;然后創(chuàng)建上述接口的代理對象,調(diào)用異步方法,響應(yīng)成功后走onResponse,失敗走onFailure;
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
apiService = retrofit.create(ApiService.class);
apiService .enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
當(dāng)然實際應(yīng)用中要比上述中復(fù)雜的多,本系列將基于retrofit 2依次學(xué)習(xí):注解,Converter,CallAdapter;
添加依賴:
compile 'com.squareup.retrofit2:retrofit:2.2.0'
注解
Retrofit 共22個注解,分為三類:HTTP請求方式,標記類,參數(shù)類;
HTTP請求方式:@GET,@POST
- 因為Retrofit 2.0使用了新的URL定義方式,BaseUrl與@POST 不是簡單的組合在一起,所以BaseUrl根域名和@POST 中路徑組合時應(yīng)按照:
BaseUrl: 以 / 結(jié)尾,@GET或者@POST: 不以 / 開頭的標準,如圖所示:
否則將出現(xiàn)的問題,如下圖所示:
標記類:@FormUrlEncoded,@Multipart,@Streaming
@FormUrlEncoded
表明是一個表單格式的請求(Content-Type:application/x-www-form-urlencoded)-
@Multipart
表明是一個請求體支持文件上傳的請求(Content-Type:multipart/form-data)- Content-Type只能是一種類型,不能同時使用上面兩種注解。
@Streaming
下載大文件需要注入,防止下載過程中寫入到內(nèi)存中
參數(shù)類:@Field,@FieldMap,@Query,@QueryMap,@Url,@Path,@Part,@Body
- @Field,@FieldMap
用于@post請求方式時傳遞簡單的鍵值對,@Field或@FieldMap傳遞的參數(shù)時放在請求體的。額外需要添加@FormUrlEncoded表示表單提交。
如果在@post請求中使用@Field和@FieldMap時去掉@FromUrlEncoded,那么程序會拋出java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1)的錯誤異常。
如果將@FromUrlEncoded添加在@GET上面,同樣的也會拋出
java.lang.IllegalArgumentException:FormUrlEncoded can only be specified on HTTP methods with request body (e.g., @POST).的錯誤異常。
//一個參數(shù)
@FormUrlEncoded
@POST("API/public")
Call<ResponseBody> postData(@Field("uid") String uid);
//參數(shù)較多
@FormUrlEncoded
@POST("API/public")
Call<ResponseBody> postData(@FieldMap Map<String, String> params);
-
@Query,@QueryMap
用于@get請求方式,傳遞簡單的鍵值對,參數(shù)將直接拼接在url后面的
//只有一個參數(shù)且參數(shù)key值:uid
@GET("API/public")
Call<ResponseBody> getData(@Query("uid") String uid);
//參數(shù)較多
@GET("API/public")
Call<ResponseBody> getData(@QueryMap Map<String, String> params);
@Url
使用全路徑復(fù)寫baseUrl,適用于非統(tǒng)一baseUrl的場景,意思是當(dāng)@GET或@POST注解的url為全路徑時(如果和baseUrl不是一個路徑),會直接使用@Url注解中新的路徑。@Path
用于替換和動態(tài)更新,如下所示使用@Path時,id 所表示的路徑中不能包含”/”,否則會將其轉(zhuǎn)化為%2F。@Part
實現(xiàn)圖片和參數(shù)上傳,如果圖片不確定@PartMap() Map<String, RequestBody> maps代替@Part MultipartBody.Part file
@Multipart
@POST("API/public")
Call<ResponseBody> upload(@PartMap Map<String, String> params,//參數(shù)集合
@Part MultipartBody.Part file);//圖片
// 封裝 請求參數(shù)集合 map
...
// 封裝 請求RequestBody
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part body =
MultipartBody.Part.createFormData("image", file.getName(), requestFile);
//
Call<ResponseBody> call = service.upload(maps,description,body);
...
-
@Body
也可以實現(xiàn)多張圖片和參數(shù)的上傳
//上傳圖片
@POST("API/public/ChangeUserImg")
Call<ResponseBody> upFile(@Body RequestBody Body);
MultipartBody.Builder builder = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("uid", mUid)
.addFormDataPart("pid", mPid);
for (int i = 0; i < mPathList.size(); i++) {
File file = new File(mPathList.get(i));
builder.addFormDataPart("file" + i, file.getName(), RequestBody.create(MediaType.parse("image/*"), file));
}
RequestBody body = builder.build();
Call<ResponseBody> call = service.upFile(body);
...
可以上傳json數(shù)據(jù)
@POST("/uploadJson")
Call<ResponseBody> postJson(@Body RequestBody jsonBody);
RequestBody body=
RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), jsonString);
Call<ResponseBody> call = APIService.postJson(requestBody);
...
Converter
默認情況下,Retrofit只能將HTTP請求體反序列化為OkHttp的ResponseBody類型,它只能接受它的RequestBody類型,
但是實際應(yīng)用中會根據(jù)項目需求規(guī)定要轉(zhuǎn)換的響應(yīng)體類型,這時就需要添加轉(zhuǎn)換器來支持其他類型,官方提供了六個序列化庫,方便大家使用;

實際中Gson的序列化庫是最常用的:
首先添加依賴:compile 'com.squareup.retrofit2:converter-gson:2.0.2'
通過GsonConverterFactory為Retrofit添加Gson支持:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
根據(jù)json結(jié)構(gòu)生成實體bean類(ApiBeans),也就是請求的響應(yīng)體類型
public interface ApiService {
@GET("api/public")
Call<ApiBeans> getData();
}
CallAdapter
retrofit和rxjava的結(jié)合使用就是同CallAdapter來實現(xiàn)的
首先導(dǎo)入依賴:
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
通過RxJavaCallAdapterFactory為Retrofit添加RxJava 2支持:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
retrofit 可以提供多個CallAdapter,比如同時添加rxjava 1的支持,但也需要導(dǎo)入rxjava 1 的依賴和通過RxJavaCallAdapterFactory為Retrofit添加RxJava 1支持。
對于retrofit的學(xué)習(xí)才剛剛開始!
retrofit :入門
retrofit :Json數(shù)據(jù)緩存
retrofit :文件斷點下載


