獲取實例
獲取 OkHttpClient.Builder
對象:
OkHttpClient.Builder builder = new OkHttpClient.Builder();
Log信息攔截器
Debug
模式查看網(wǎng)絡請求、打印Log
信息申鱼,發(fā)布時不需要Log
。
添加依賴
項目的build.gradle
添加:
compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'
設置攔截器
if(BuildConfig.DEBUG){
//Log信息攔截器
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
//設置Log
builder.addInterceptor(loggingInterceptor);
}
緩存機制
無網(wǎng)絡時柴灯,也能顯示數(shù)據(jù)。
File cacheFile = new File(MyApplication.getContext().getExternalCacheDir(), "DemoCache");
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(MyApplication.getContext())) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response response = chain.proceed(request);
if (AppUtils.networkIsAvailable(MyApplication.getContext())) {
int maxAge = 0;
// 有網(wǎng)絡時 設置緩存超時時間0個小時
response.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.removeHeader("Demo")// 清除頭信息捞魁,因為服務器如果不支持,會返回一些干擾信息离咐,不清除下面無法生效
.build();
} else {
// 無網(wǎng)絡時谱俭,設置超時為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);
公共參數(shù)
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);
請求頭
以下為初始配置方式添加請求頭,另一種為定義接口方式宵蛀,詳見注解篇 @Headers
昆著。
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
,看需求术陶。
添加依賴
項目的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 轉(zhuǎn)換器
.addConverterFactory(GsonConverterFactory.create())
//RxJava 適配器
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(okHttpClient)
.build();
Json轉(zhuǎn)換器
默認情況,Retrofit
只能反序列化 Http bodies
為 OkHttp
的 ResponseBody
且只能接受它為 @Body
的類型梧宫。
Retrofit 2.0
支持多種解析方式來解析響應數(shù)據(jù):
-
Gson::
com.squareup.retrofit2:converter-gson
-
Jackson:
com.squareup.retrofit2:converter-jackson
-
Moshi:
com.squareup.retrofit2:converter-moshi
-
Protobuf:
com.squareup.retrofit2:converter-protobuf
-
Wire:
com.squareup.retrofit2:converter-wire
-
Simple XML:
com.squareup.retrofit2:converter-simplexml
- Scalars (primitives, boxed, and String):
com.squareup.retrofit2:converter-scalars
自定義轉(zhuǎn)換器
繼承Converter.Factory class
http://simple.sourceforge.net/
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.nuuneoi.com/base/")
.addConverterFactory(GsonConverterFactory.create())
.build();
RxJava
除了提供 Callback
形式的API
接谨,還有RxJava
版本的 Observable
形式API
。
添加依賴
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta3'
compile 'io.reactivex:rxandroid:1.0.1'
設置
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.nuuneoi.com/base/")
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
栗子一:獲取一個User
對象的接口
Callback 方式:
//定義請求
@GET("/user")
public void getUser(@Query("userId") String userId, Callback<User> callback);
//使用
getUser(userId, new Callback<User>() {
@Override
public void success(User user) {
userView.setUser(user);
}
@Override
public void failure(RetrofitError error) {
// Error handling
...
}
};
Rxjava 方式:
//定義請求
@GET("/user")
public Observable<User> getUser(@Query("userId") String userId);
//使用
getUser(userId)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@Override
public void onNext(User user) {
userView.setUser(user);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable error) {
// Error handling
...
}
});
栗子二:獲取到的 User 不直接顯示塘匣,先與數(shù)據(jù)庫中的數(shù)據(jù)比對修正后再顯示
Callback 方式:
getUser(userId, new Callback<User>() {
@Override
public void success(User user) {
processUser(user); // 嘗試修正 User 數(shù)據(jù)
userView.setUser(user);
}
@Override
public void failure(RetrofitError error) {
// Error handling
...
}
};
注意:數(shù)據(jù)庫操作屬耗時操作脓豪,所以要避免在主線程中操作數(shù)據(jù)庫。
//修改后
getUser(userId, new Callback<User>() {
@Override
public void success(User user) {
new Thread() {
@Override
public void run() {
processUser(user); // 嘗試修正 User 數(shù)據(jù)
runOnUiThread(new Runnable() { // 切回 UI 線程
@Override
public void run() {
userView.setUser(user);
}
});
}
}).start();
}
@Override
public void failure(RetrofitError error) {
// Error handling
...
}
};
Rxjava 方式:
getUser(userId)
.doOnNext(new Action1<User>() {
@Override
public void call(User user) {
processUser(user);
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@Override
public void onNext(User user) {
userView.setUser(user);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable error) {
// Error handling
...
}
});
栗子三:/user
接口不能直接訪問忌卤,需要填入在線獲取的 token
Callback 方式:可以嵌套Callback
@GET("/token")
public void getToken(Callback<String> callback);
@GET("/user")
public void getUser(@Query("token") String token, @Query("userId") String userId, Callback<User> callback);
...
getToken(new Callback<String>() {
@Override
public void success(String token) {
getUser(token, userId, new Callback<User>() {
@Override
public void success(User user) {
userView.setUser(user);
}
@Override
public void failure(RetrofitError error) {
// Error handling
...
}
};
}
@Override
public void failure(RetrofitError error) {
// Error handling
...
}
});
Rxjava 方式:
@GET("/token")
public Observable<String> getToken();
@GET("/user")
public Observable<User> getUser(@Query("token") String token, @Query("userId") String userId);
...
getToken()
.flatMap(new Func1<String, Observable<User>>() {
@Override
public Observable<User> onNext(String token) {
return getUser(token, userId);
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@Override
public void onNext(User user) {
userView.setUser(user);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable error) {
// Error handling
...
}
});
完整配置
public class AppClient {
public static Retrofit retrofit = null;
public static Retrofit retrofit() {
if (retrofit == null) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
/**
* 設置緩存
*/
/**
* 公共參數(shù)
*/
/**
* 設置頭
*/
/**
* Log信息攔截器
*/
/**
* 設置cookie
*/
/**
* 設置超時和重連
*/
//以上設置完成
OkHttpClient okHttpClient = builder.build();
retrofit = new Retrofit.Builder()
.baseUrl(ApiStores.API_SERVER_URL)
//設置 Json 轉(zhuǎn)換器
.addConverterFactory(GsonConverterFactory.create())
//RxJava 適配器
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(okHttpClient)
.build();
}
return retrofit;
}
}
混淆配置
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on RoboVM on iOS. Will not be used at runtime.
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions