Android Retrofit 2.0 使用-補充篇
推薦閱讀,猛戳:
1、Android MVP 實例2、Android Retrofit 2.0使用3、RxJava
4、RxBus5、Android MVP+Retrofit+RxJava實踐小結之前分享的Android Retrofit 2.0 使用,屬於基本的使用,實際開發還遠遠不夠,因此對其補充,主要在Retrofit配置和介面參數。
Retrofit配置
添加依賴
app/build.gradle
compile com.squareup.retrofit2:retrofit:2.0.2n
首先Builder(),得到OkHttpClient.Builder對象builder
OkHttpClient.Builder builder = new OkHttpClient.Builder();n
Log信息攔截器
Debug可以看到,網路請求,列印Log信息,發布的時候就不需要這些log
1、添加依賴app/build.gradlecompile com.squareup.okhttp3:logging-interceptor:3.1.2n
2、Log信息攔截器
if (BuildConfig.DEBUG) {n // Log信息攔截器n HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();n loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);n //設置 Debug Log 模式n builder.addInterceptor(loggingInterceptor);n}n
緩存機制
無網路時,也能顯示數據
File cacheFile = new File(DemoApplication.getContext().getExternalCacheDir(), "WuXiaolongCache");nCache cache = new Cache(cacheFile, 1024 * 1024 * 50);nInterceptor cacheInterceptor = new Interceptor() {n @Overriden public Response intercept(Chain chain) throws IOException {n Request request = chain.request();n if (!AppUtils.networkIsAvailable(DemoApplication.getContext())) {n request = request.newBuilder()n .cacheControl(CacheControl.FORCE_CACHE)n .build();n }n Response response = chain.proceed(request);n if (AppUtils.networkIsAvailable(DemoApplication.getContext())) {n int maxAge = 0;n // 有網路時 設置緩存超時時間0個小時n response.newBuilder()n .header("Cache-Control", "public, max-age=" + maxAge)n .removeHeader("WuXiaolong")// 清除頭信息,因為伺服器如果不支持,會返回一些干擾信息,不清除下面無法生效n .build();n } else {n // 無網路時,設置超時為4周n int maxStale = 60 * 60 * 24 * 28;n response.newBuilder()n .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)n .removeHeader("nyn")n .build();n }n return response;n }n};nbuilder.cache(cache).addInterceptor(cacheInterceptor);n
公共參數
可能介面有某些參數是公共的,不可能一個個介面都去加吧
//公共參數nInterceptor addQueryParameterInterceptor = new Interceptor() {n @Overriden public Response intercept(Chain chain) throws IOException {n Request originalRequest = chain.request();n Request request;n String method = originalRequest.method();n Headers headers = originalRequest.headers();n HttpUrl modifiedUrl = originalRequest.url().newBuilder()n // Provide your custom parameter heren .addQueryParameter("platform", "android")n .addQueryParameter("version", "1.0.0") n .build();n request = originalRequest.newBuilder().url(modifiedUrl).build();n return chain.proceed(request);n }n};n//公共參數nbuilder.addInterceptor(addQueryParameterInterceptor);n
設置頭
有的介面可能對請求頭要設置
Interceptor headerInterceptor = new Interceptor() {n @Overriden public Response intercept(Chain chain) throws IOException {n Request originalRequest = chain.request();n Request.Builder requestBuilder = originalRequest.newBuilder()n .header("AppType", "TPOS")n .header("Content-Type", "application/json")n .header("Accept", "application/json")n .method(originalRequest.method(), originalRequest.body());n Request request = requestBuilder.build();n return chain.proceed(request);n }n};n//設置頭nbuilder.addInterceptor(headerInterceptor );n
設置cookie
服務端可能需要保持請求是同一個cookie,主要看各自需求
1、app/build.gradle
compile com.squareup.okhttp3:okhttp-urlconnection:3.2.0n
2、設置cookie
CookieManager cookieManager = new CookieManager();ncookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);nbuilder.cookieJar(new JavaNetCookieJar(cookieManager));n
設置超時和重連
希望超時時能重連
//設置超時n builder.connectTimeout(15, TimeUnit.SECONDS);n builder.readTimeout(20, TimeUnit.SECONDS);n builder.writeTimeout(20, TimeUnit.SECONDS);n //錯誤重連n builder.retryOnConnectionFailure(true);n
最後將這些配置設置給retrofit:
OkHttpClient okHttpClient = builder.build();nRetrofit retrofit = new Retrofit.Builder()n .baseUrl(ApiStores.API_SERVER_URL)n //設置 Json 轉換器n .addConverterFactory(GsonConverterFactory.create())n //RxJava 適配器n .addCallAdapterFactory(RxJavaCallAdapterFactory.create())n .client(okHttpClient)n .build();n
完整配置
public class AppClient {n public static Retrofit retrofit = null;nn public static Retrofit retrofit() {n if (retrofit == null) {n OkHttpClient.Builder builder = new OkHttpClient.Builder();n /**n *設置緩存,代碼略n */n n /**n * 公共參數,代碼略n */n n /**n * 設置頭,代碼略n */ n n /**n * Log信息攔截器,代碼略n */n n /**n * 設置cookie,代碼略n */n n /**n * 設置超時和重連,代碼略n */nn //以上設置結束,才能build(),不然設置白搭n OkHttpClient okHttpClient = builder.build();nn retrofit = new Retrofit.Builder()n .baseUrl(ApiStores.API_SERVER_URL) n .client(okHttpClient)n .build();n }n return retrofit;nn }n}n
介面參數
Path
類似這樣鏈接:http://wuxiaolong.me/2016/01/...
@GET("2016/01/15/{retrofit}")n Call<ResponseBody> getData(@Path("retrofit") String retrofit);n
即您傳的參數retrofit內容會替換大括弧里的內容。
Query
類似這樣鏈接:http://wuxiaolong.me/v1?ip=20...
@GET("v1")nCall<ResponseBody> getData(@Query("ip") String ip,@Query("name") String name);n
Field
表單提交,如登錄
@FormUrlEncodedn @POST("v1/login")n Call<ResponseBody> userLogin(@Field("phone") String phone, @Field("password") String password);n
傳json格式
如果參數是json格式,如:
{ n "apiInfo": { n "apiName": "WuXiaolong", n "apiKey": "666" n } n} n
建立Bean
public class ApiInfo {n private ApiInfoBean apiInfo;nn public ApiInfoBean getApiInfo() {n return apiInfo;n }nn public void setApiInfo(ApiInfoBean apiInfo) {n this.apiInfo = apiInfo;n }nn public class ApiInfoBean {n private String apiName;n private String apiKey;n //省略get和set方法n }n }n
ApiStores
@POST("client/shipper/getCarType")nCall<ResponseBody> getData(@Body ApiInfo apiInfo);n
代碼調用
ApiInfo apiInfo = new ApiInfo();nApiInfo.ApiInfoBean apiInfoBean = apiInfo.new ApiInfoBean();napiInfoBean.setApiKey("666");napiInfoBean.setApiName("WuXiaolong");napiInfo.setApiInfo(apiInfoBean);n//調介面ngetData(apiInfo);n
傳數組
@GET("v1/enterprise/find")nCall<ResponseBody> getData(@Query("id") String id, @Query("linked[]") String... linked);n
代碼調用
String id="WuXiaolong";nString[] s = new String[]{"WuXiaolong"};n//調介面ngetData(id, s);n
傳文件-單個
@Multipartn@POST("v1/create")nCall<ResponseBody> create(@Part("pictureName") RequestBody pictureName, @Part MultipartBody.Part picture);n
代碼調用
RequestBody pictureNameBody = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), "pictureName");nFile picture= new File(path);nRequestBody requestFile = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), picture);n// MultipartBody.Part is used to send also the actual file namenMultipartBody.Part picturePart = MultipartBody.Part.createFormData("picture", picture.getName(), requestFile);n//調介面ncreate(pictureNameBody, picturePart);n
傳文件-多個
@Multipartn@POST("v1/create")nCall<ResponseBody> create(@Part("pictureName") RequestBody pictureName, @PartMap Map<String, RequestBody> params);n
代碼調用
RequestBody pictureNameBody = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), "pictureName");nFile picture= new File(path);nRequestBody requestFile = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), picture);nMap<String, RequestBody> params = new HashMap<>();nparams.put("picture"; filename="" + picture.getName() + "", requestFile);n//調介面ncreate(pictureNameBody, params);n
聯繫我
我的微信公眾號:吳小龍同學,個人博客:http://wuxiaolong.me/,Android技術交流群:②群 376526418;③群 370527306
推薦閱讀:
※Windows 10 Mobile 開發人員模式和安卓系統的 USB調試等開發者功能有何異同?
※如何看待最近國產 Android 應用程序紛紛放棄 Android Design 的現象?
※如何用Android Studio進行無線的真機調試?
※開發者在使用Andoid 6.0 新功能需要注意的地方有哪些?
※如何評價魅族關於魅藍的文案?
TAG:Android |