Android Retrofit 2.0 使用-補充篇

推薦閱讀,猛戳:java

一、Android MVP 實例android

二、Android Retrofit 2.0使用json

三、RxJavaapi

四、RxBus數組

五、Android MVP+Retrofit+RxJava實踐小結緩存

以前分享的Android Retrofit 2.0 使用,屬於基本的使用,實際開發還遠遠不夠,所以對其補充,主要在Retrofit配置和接口參數。服務器

Retrofit配置

添加依賴

app/build.gradle微信

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

首先Builder(),獲得OkHttpClient.Builder對象buildercookie

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

Log信息攔截器

Debug能夠看到,網絡請求,打印Log信息,發佈的時候就不須要這些log 一、添加依賴 app/build.gradle網絡

compile 'com.squareup.okhttp3:logging-interceptor:3.1.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,主要看各自需求 一、app/build.gradle

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

二、設置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);

代碼調用

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);

微信公衆號

歡迎微信掃一掃關注:不止於技術分享,天天進步一點點。

關於做者

點擊查看

相關文章
相關標籤/搜索