推薦閱讀,猛戳:
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.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);
代碼調用
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);
微信公眾號
歡迎微信掃一掃關注:不止於技術分享,每天進步一點點。