標籤:

Android Retrofit 2.0 使用-補充篇

推薦閱讀,猛戳:

1、Android MVP 實例

2、Android Retrofit 2.0使用

3、RxJava

4、RxBus

5、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.gradle

compile 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

聯繫我

我的微信公眾號:吳小龍同學,個人博客:wuxiaolong.me/,Android技術交流群:②群 376526418;③群 370527306


推薦閱讀:

Windows 10 Mobile 開發人員模式和安卓系統的 USB調試等開發者功能有何異同?
如何看待最近國產 Android 應用程序紛紛放棄 Android Design 的現象?
如何用Android Studio進行無線的真機調試?
開發者在使用Andoid 6.0 新功能需要注意的地方有哪些?
如何評價魅族關於魅藍的文案?

TAG:Android |