Android Retrofit 2.0 使用-補充篇

swkm4244 8年前發布 | 20K 次閱讀 Retrofit Android開發 移動開發

之前分享的 Android Retrofit 2.0 使用 ,屬于基本的使用,實際開發還遠遠不夠,因此對其補充,主要在Retrofit配置和接口參數。

Retrofit配置

添加依賴

app/build.gradle

compile 'com.squareup.retrofit2:retrofit:2.0.2'

首先Builder(),得到OkHttpClient.Builder對象builder

OkHttpClient.Builder builder = new OkHttpClient.Builder();

Log信息攔截器

Debug可以看到,網絡請求,打印Log信息,發布的時候就不需要這些log

1、添加依賴

app/build.gradle

compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'

2、Log信息攔截器

if (BuildConfig.DEBUG) {
    // Log信息攔截器
    HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
    loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    //設置 Debug Log 模式
    builder.addInterceptor(loggingInterceptor);
}

緩存機制

無網絡時,也能顯示數據

File cacheFile = new File(DemoApplication.getContext().getExternalCacheDir(), "WuXiaolongCache");
Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);
Interceptor cacheInterceptor = new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        if (!AppUtils.networkIsAvailable(DemoApplication.getContext())) {
            request = request.newBuilder()
                    .cacheControl(CacheControl.FORCE_CACHE)
                    .build();
        }
        Response response = chain.proceed(request);
        if (AppUtils.networkIsAvailable(DemoApplication.getContext())) {
            int maxAge = 0;
            // 有網絡時 設置緩存超時時間0個小時
            response.newBuilder()
                    .header("Cache-Control", "public, max-age=" + maxAge)
                    .removeHeader("WuXiaolong")// 清除頭信息,因為服務器如果不支持,會返回一些干擾信息,不清除下面無法生效
                    .build();
        } else {
            // 無網絡時,設置超時為4周
            int maxStale = 60 * 60 * 24 * 28;
            response.newBuilder()
                    .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                    .removeHeader("nyn")
                    .build();
        }
        return response;
    }
};
builder.cache(cache).addInterceptor(cacheInterceptor);

公共參數

可能接口有某些參數是公共的,不可能一個個接口都去加吧

//公共參數
Interceptor addQueryParameterInterceptor = new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request originalRequest = chain.request();
        Request request;
        String method = originalRequest.method();
        Headers headers = originalRequest.headers();
        HttpUrl modifiedUrl = originalRequest.url().newBuilder()
                // Provide your custom parameter here
                .addQueryParameter("platform", "android")
                .addQueryParameter("version", "1.0.0")              
                .build();
        request = originalRequest.newBuilder().url(modifiedUrl).build();
        return chain.proceed(request);
    }
};
//公共參數
builder.addInterceptor(addQueryParameterInterceptor);

設置頭

有的接口可能對請求頭要設置

Interceptor headerInterceptor = new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request originalRequest = chain.request();
        Request.Builder requestBuilder = originalRequest.newBuilder()
                .header("AppType", "TPOS")
                .header("Content-Type", "application/json")
                .header("Accept", "application/json")
                .method(originalRequest.method(), originalRequest.body());
        Request request = requestBuilder.build();
        return chain.proceed(request);
    }
};
//設置頭
builder.addInterceptor(headerInterceptor );

設置cookie

服務端可能需要保持請求是同一個cookie,主要看各自需求

1、app/build.gradle

compile 'com.squareup.okhttp3:okhttp-urlconnection:3.2.0'

2、設置cookie

CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
builder.cookieJar(new JavaNetCookieJar(cookieManager));

設置超時和重連

希望超時時能重連

//設置超時
builder.connectTimeout(15, TimeUnit.SECONDS);
builder.readTimeout(20, TimeUnit.SECONDS);
builder.writeTimeout(20, TimeUnit.SECONDS);
//錯誤重連
builder.retryOnConnectionFailure(true);

最后將這些配置設置給retrofit:

OkHttpClient okHttpClient = builder.build();
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(ApiStores.API_SERVER_URL)
        //設置 Json 轉換器
        .addConverterFactory(GsonConverterFactory.create())
        //RxJava 適配器
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .client(okHttpClient)
        .build();

完整配置

public class AppClient {
    public static Retrofit retrofit = null;

    public static Retrofit retrofit() {
        if (retrofit == null) {
             OkHttpClient.Builder builder = new OkHttpClient.Builder();
            /**
 *設置緩存,代碼略
 */

            /**
 * 公共參數,代碼略
 */

            /**
 * 設置頭,代碼略
 */           

             /**
 * Log信息攔截器,代碼略
 */

             /**
 * 設置cookie,代碼略
 */

             /**
 * 設置超時和重連,代碼略
 */

            //以上設置結束,才能build(),不然設置白搭
            OkHttpClient okHttpClient = builder.build();

            retrofit = new Retrofit.Builder()
                    .baseUrl(ApiStores.API_SERVER_URL)                  
                    .client(okHttpClient)
                    .build();
        }
        return retrofit;

    }
}

接口參數

Path

類似這樣鏈接: http://wuxiaolong.me/2016/01/15/retrofit/

@GET("2016/01/15/{retrofit}")
Call<ResponseBody> getData(@Path("retrofit") String retrofit);

即您傳的參數retrofit內容會替換大括號里的內容。

Query

類似這樣鏈接: http://wuxiaolong.me/v1?ip=202.202.33.33&name=WuXiaolong

@GET("v1")
Call<ResponseBody> getData(@Query("ip") String ip,@Query("name") String name);

Field

表單提交,如登錄

@FormUrlEncoded
@POST("v1/login")
Call<ResponseBody> userLogin(@Field("phone") String phone, @Field("password") String password);

傳json格式

如果參數是json格式,如:

{       
    "apiInfo": {        
        "apiName": "WuXiaolong",        
        "apiKey": "666"     
    }       
}

建立Bean

public class ApiInfo {
       private ApiInfoBean apiInfo;

       public ApiInfoBean getApiInfo() {
           return apiInfo;
       }

       public void setApiInfo(ApiInfoBean apiInfo) {
           this.apiInfo = apiInfo;
       }

       public class ApiInfoBean {
           private String apiName;
           private String apiKey;
           //省略get和set方法
       }
   }

ApiStores

@POST("client/shipper/getCarType")
Call<ResponseBody> getData(@Body ApiInfo apiInfo);
```       

代碼調用
```java
ApiInfo apiInfo = new ApiInfo();
ApiInfo.ApiInfoBean apiInfoBean = apiInfo.new ApiInfoBean();
apiInfoBean.setApiKey("666");
apiInfoBean.setApiName("WuXiaolong");
apiInfo.setApiInfo(apiInfoBean);
//調接口
getData(apiInfo);

傳數組

@GET("v1/enterprise/find")
Call<ResponseBody> getData(@Query("id") String id, @Query("linked[]") String... linked);

代碼調用

String id="WuXiaolong";
String[] s = new String[]{"WuXiaolong"};
//調接口
getData(id, s);

傳文件-單個

@Multipart
@POST("v1/create")
Call<ResponseBody> create(@Part("pictureName") RequestBody pictureName, @Part MultipartBody.Part picture);

代碼調用

RequestBody pictureNameBody = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), "pictureName");
File picture= new File(path);
RequestBody requestFile = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), picture);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part picturePart = MultipartBody.Part.createFormData("picture", picture.getName(), requestFile);
//調接口
create(pictureNameBody, picturePart);

傳文件-多個

@Multipart
@POST("v1/create")
Call<ResponseBody> create(@Part("pictureName") RequestBody pictureName, @PartMap Map<String, RequestBody> params);

代碼調用

RequestBody pictureNameBody = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), "pictureName");
File picture= new File(path);
RequestBody requestFile = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), picture);
Map<String, RequestBody> params = new HashMap<>();
params.put("picture\"; filename=\"" + picture.getName() + "", requestFile);
//調接口
create(pictureNameBody, params);

來自: http://wuxiaolong.me/2016/06/18/retrofits/

 本文由用戶 swkm4244 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!