Retrofit是由Square公司開發的類型安全HTTP客戶端框架,借助動態代理在運行時生成接口實現類,將注解轉化為OkHttp請求配置;節省成本通過轉換器(Gson/Moshi)自動序列化JSON/XML,內部處理網絡請求在主線程返回報文。Retrofit 直譯是封裝、翻版。他就是對okhttp做了進一步封裝,方便使用,它底層的所有請求默認走的都是Okhttp。 ?所以使用Retrofit必須依賴okHttp。
兩者區別:Retrofit是基于App發請求的封裝,也就是面向的應用層(比如響應數據的處理和錯誤處理等),而Okhhtp是對底層網絡請求的封裝與優化(socket優化,數據壓縮,buffer緩存等)。
本文將通過GET/POSTde 基礎請求、文件上傳、動態URL、緩存、轉換器,以及借助OKHttp實現Retrofit請求過程中設置請求頭、cookie、超時時間和攔截器都是借助OkHttpClient 等。
1、添加依賴:
使用Retrofit添加的依賴,另外,使用轉換器也需要在build.gradle中單獨引入,兩種轉換器通常不必同時使用,根據項目JSON處理需求選擇其一即可:
dependencies {implementation 'com.squareup.retrofit2:retrofit:2.9.0'
}
GsonConverterFactory依賴配置:
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.google.code.gson:gson:2.8.8'
MoshiConverterFactory依賴配置:?
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
implementation 'com.squareup.moshi:moshi:1.14.0' // Moshi
2、業務場景實現
先定義一個接口:
切記這里必須是interface!!!
public interface RequestService {@GET("login/{id}")Call<LoginInfo> login(@Path("id") int userId);@POST("users/new")@Headers("Content-Type: application/json") // 設置請求頭Call<ResponseBody> loginPost(@Body LoginInfo loginInfo); // @Body注解表示請求體@Multipart // 表示多部分請求@POST("upload")Call<ResponseBody> uploadFile( @Part("description") RequestBody description, @Part MultipartBody.Part file);// 借助@Url注解,指定完整URL@GETCall<ResponseBody> getCustomUrl(@Url String url);//借助Query注解,添加查詢參數@GET("search")Call<ResponseBody> queryData(@Query("q") String query);}
定義實體類 LoginInfo.java :
public class LoginInfo {private String userNmae;private String userPwd;public LoginInfo(String userNmae, String userPwd) {this.userNmae = userNmae;this.userPwd = userPwd;}
}
定義初始化Retrofit的單例工具類 RetrofitUtil.java :
public class RetrofitUtil {private static RetrofitUtil retrofitUtil;private Retrofit retrofit;File httpCacheDirectory = new File(BaseApplication.getContext().getCacheDir(), "responses");int cacheSize = 10 * 1024 * 1024; // 10MBCache cache = new Cache(httpCacheDirectory, cacheSize);private RetrofitUtil(){}public static RetrofitUtil getInstance(){synchronized (RetrofitUtil.class){if (retrofitUtil == null){retrofitUtil = new RetrofitUtil();}return retrofitUtil;}}public <T> T getServer(Class<T> cls, String baseUrl){if (retrofit == null){retrofit = new Retrofit.Builder().baseUrl(baseUrl).client(getClient()).addConverterFactory(GsonConverterFactory.create()).build();}return retrofit.create(cls);}public OkHttpClient getClient(){// 創建OkHttpClientOkHttpClient okHttpClient = new OkHttpClient.Builder()
// .cookieJar().connectTimeout(10, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS).writeTimeout(10, TimeUnit.SECONDS).addInterceptor(new Interceptor() {@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request();// 添加統一請求頭request = request.newBuilder().header("Cache-Control", "public, max-age=60").build();return chain.proceed(request);}}).cache(cache).build();return okHttpClient;}
}
注意Retrofit在設置請求頭、cookie、超時時間和攔截器都是借助OkHttpClient 來實現。
2.1 Get請求
getTv.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {int id = 600001;RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).login(id).enqueue(new Callback<LoginInfo>() {@Overridepublic void onResponse(Call<LoginInfo> call, Response<LoginInfo> response) {if (response.isSuccessful()) {LoginInfo loginInfo = response.body(); // 自動解析JSON為User對象}}@Overridepublic void onFailure(Call<LoginInfo> call, Throwable t) {t.printStackTrace();}});}
});
2.2 POST請求
LoginInfo loginInfo = new LoginInfo("Admin", "12345678");
// 發起請求
Call<ResponseBody> call = RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).loginPost(loginInfo);
call.enqueue(new Callback<ResponseBody>() {@Overridepublic void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {// 請求成功}@Overridepublic void onFailure(Call<ResponseBody> call, Throwable t) {// 請求失敗}
});
2.3 文件上傳
// 準備文件
File file = new File("path/to/file.jpg");
RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpeg"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", file.getName(), requestFile);// 發起上傳請求
RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).uploadFile(RequestBody.create(MediaType.parse("text/plain"), "文件描述"),body).enqueue(new Callback<ResponseBody>() {@Overridepublic void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {//處理上傳成功后的邏輯}@Overridepublic void onFailure(Call<ResponseBody> call, Throwable t) {//處理上傳失敗的邏輯}
});
2.4動態指定URL和添加查詢參數
一般來說一個項目中你可能定封裝了公共個請求路徑和域名,但有個別接口就需要特立獨行的地址和傳參,此時可以借助@Url和@Query動態的實現。 兩個請求也在上面給出的RequestService 這個接口中定義了。
// 使用動態URLCall<ResponseBody> call1 = RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).getCustomUrl("https://api.example.com/custom/path");// 使用查詢參數Call<ResponseBody> call2 = RetrofitUtil.getInstance().getServer(RequestService.class,mUrl).queryData("retrofit");
個人總結記錄,才疏學淺,如有錯誤,歡迎指正,多謝。?