一题造、Retrofit簡(jiǎn)介
Retrofit是Square公司開發(fā)的一款針對(duì)Android網(wǎng)絡(luò)請(qǐng)求的框架捺癞,Retrofit2底層基于OkHttp實(shí)現(xiàn)
Retrofit執(zhí)行網(wǎng)絡(luò)請(qǐng)求
以一個(gè)GET請(qǐng)求為例,執(zhí)行網(wǎng)路請(qǐng)求所需步驟:
1.創(chuàng)建業(yè)務(wù)請(qǐng)求接口
public interface BlueService {
@GET("book/search")
Call<BookSearchResponse> getSearchBooks(@Query("q") String name,
@Query("tag") String tag, @Query("start") int start,
@Query("count") int count);
}
2.需要?jiǎng)?chuàng)建一個(gè)Retrofit的示例,并完成相應(yīng)的配置
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.douban.com/v2/")
.addConverterFactory(GsonConverterFactory.create())
.build();
BlueService service = retrofit.create(BlueService.class);
baseUrl就是網(wǎng)絡(luò)請(qǐng)求URL相對(duì)固定的地址拦耐,一般包括請(qǐng)求協(xié)議(如Http)婶希、域名或IP地址榕暇、端口號(hào)等,當(dāng)然還會(huì)有很多其他的配置喻杈,下文會(huì)詳細(xì)介紹拐揭。addConverterFactory方法表示需要用什么轉(zhuǎn)換器來解析返回值,GsonConverterFactory.create()表示調(diào)用Gson庫來解析json返回值
3.調(diào)用請(qǐng)求方法奕塑,并得到Call實(shí)例
-
同步請(qǐng)求
BookSearchResponse response = call.execute().body();
網(wǎng)絡(luò)請(qǐng)求一定要在子線程中完成堂污,不能直接在UI線程執(zhí)行,不然會(huì)crash
-
異步請(qǐng)求
call.enqueue(new Callback<BookSearchResponse>() { @Override public void onResponse(Call<BookSearchResponse> call, Response<BookSearchResponse> response) { asyncText.setText("異步請(qǐng)求結(jié)果: " + response.body().books.get(0).altTitle); } @Override public void onFailure(Call<BookSearchResponse> call, Throwable t) { } });
二龄砰、使用
首先需要在module的build.gradle文件中依賴相關(guān)包盟猖,配置如下
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
引入這些包后讨衣,接下來需要對(duì)不同請(qǐng)求方式進(jìn)行說明
Get方法
-
@Query
Get方法請(qǐng)求參數(shù)都會(huì)以key=value的方式拼接在url后面,Retrofit提供了兩種方式設(shè)置請(qǐng)求參數(shù)式镐。第一種就是像上文提到的直接在interface中添加@Query注解反镇,還有一種方式是通過Interceptor實(shí)現(xiàn),直接看如何通過Interceptor實(shí)現(xiàn)請(qǐng)求參數(shù)的添加娘汞。
public class CustomInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); HttpUrl httpUrl = request.url().newBuilder() .addQueryParameter("token", "tokenValue") .build(); request = request.newBuilder().url(httpUrl).build(); return chain.proceed(request); } }
ddQueryParameter就是添加請(qǐng)求參數(shù)的具體代碼歹茶,這種方式比較適用于所有的請(qǐng)求都需要添加的參數(shù),一般現(xiàn)在的網(wǎng)絡(luò)請(qǐng)求都會(huì)添加token作為用戶標(biāo)識(shí)你弦,那么這種方式就比較適合惊豺。
創(chuàng)建完成自定義的Interceptor后,還需要在Retrofit創(chuàng)建client處完成添加
addInterceptor(new CustomInterceptor())
-
@QueryMap
如果Query參數(shù)比較多禽作,那么可以通過@QueryMap方式將所有的參數(shù)集成在一個(gè)Map統(tǒng)一傳遞
public interface BlueService { @GET("book/search") Call<BookSearchResponse> getSearchBooks(@QueryMap Map<String, String> options); }
-
Query集合
假如你需要添加相同Key值尸昧,但是value卻有多個(gè)的情況,一種方式是添加多個(gè)@Query參數(shù)旷偿,還有一種簡(jiǎn)便的方式是將所有的value放置在列表中烹俗,然后在同一個(gè)@Query下完成添加,實(shí)例代碼如下:
public interface BlueService { @GET("book/search") Call<BookSearchResponse> getSearchBooks(@Query("q") List<String> name); }
-
@Path
如果請(qǐng)求的相對(duì)地址也是需要調(diào)用方傳遞萍程,那么可以使用@Path注解幢妄,示例代碼如下:
@GET("book/{id}") Call<BookResponse> getBook(@Path("id") String id);
Post請(qǐng)求
-
@field
Post請(qǐng)求需要把請(qǐng)求參數(shù)放置在請(qǐng)求體中,而非拼接在url后面茫负,先來看一個(gè)簡(jiǎn)單的例子
@FormUrlEncoded @POST("book/reviews") Call<String> addReviews(@Field("book") String bookId, @Field("title") String title, @Field("content") String content, @Field("rating") String rating);
特別說明:
-
@FormUrlEncoded將會(huì)自動(dòng)將請(qǐng)求參數(shù)的類型調(diào)整為application/x-www-form-urlencoded蕉鸳,假如content傳遞的參數(shù)為Good Luck,那么最后得到的請(qǐng)求體就是
FormUrlEncoded不能用于Get請(qǐng)求
-
@Field注解將每一個(gè)請(qǐng)求參數(shù)都存放至請(qǐng)求體中朽褪,還可以添加encoded參數(shù)置吓,該參數(shù)為boolean型无虚,具體的用法為
@Field(value = "book", encoded = true) String book
encoded參數(shù)為true的話缔赠,key-value-pair將會(huì)被編碼,即將中文和特殊字符進(jìn)行編碼轉(zhuǎn)換
2.@FieldMap
Post請(qǐng)求存在多個(gè)請(qǐng)求參數(shù)時(shí)友题,就可以使用FieldMap,使用方式如下:
@FormUrlEncoded
@POST("book/reviews")
Call<String> addReviews(@FieldMap Map<String, String> fields);
-
@Body
Post請(qǐng)求參數(shù)有多個(gè)嗤堰,統(tǒng)一封裝到類中應(yīng)該會(huì)更好,這樣維護(hù)起來會(huì)非常方便
@FormUrlEncoded @POST("book/reviews") Call<String> addReviews(@Body Reviews reviews); public class Reviews { public String book; public String title; public String content; public String rating; }
?