前言:
Retrofit作爲簡化HTTP請求的庫,已經運行多年,2.0版本依然不辱使命的在做這些事情。不過2.0版本修復了一些長期影響開發者的設計,還加入了前所未有的強大特性。在NYC2015的這一個分享中,Jake Wharton的演講涵蓋了所有Retrofit2.0的新特性,全面介紹了Retrofit2.0工作原理。看我
初始配置就看官網了,廢話不多說,開始封裝:
一、Api請求網絡配置
(1)添加所需要的配置:
public class NetConfig {
File RESPONSE_CACHE;//緩存文件
int RESPONSE_CACHE_SIZE;//緩存文件大小
int CONNET_TIMEOUT;//連接超時
int READ_TIMEOUT;//讀取新鏈接超時
int MAX_CACHE_AGE;//從文檔被訪問後的存活時間
Context context;
public NetConfig(File RESPONSE_CACHE,int RESPONSE_CACHE_SIZE,int CONNET_TIMEOUT,int READ_TIMEOUT,int MAX_CACHE_AGE,Context context){
this.RESPONSE_CACHE = RESPONSE_CACHE;
this.RESPONSE_CACHE_SIZE = RESPONSE_CACHE_SIZE;
this.CONNET_TIMEOUT = CONNET_TIMEOUT;
this.READ_TIMEOUT = READ_TIMEOUT;
this.MAX_CACHE_AGE = MAX_CACHE_AGE;
this.context = context;
}
}
(2)通過構建者模式設置默認初始網絡配置
public class NetConfigBuilder {
private File response_cache;
private int response_cache_size = 5 * 1024 * 1024;
private int connect_timeout = 8 * 1000;
private int read_timeout = 5 * 1000;
private Context appContext;
private int maxCacheAge = 0;
/**
* request cache-control
*/
public NetConfigBuilder maxCacheAge(int maxCacheAge) {
this.maxCacheAge = maxCacheAge;
return this;
}
/**
* local cache dir
*/
public NetConfigBuilder responseCacheDir(File response_cache) {
this.response_cache = response_cache;
return this;
}
/**
* local cache size
*/
public NetConfigBuilder responseCacheSize(int response_cache_size) {
this.response_cache_size = response_cache_size;
return this;
}
/**
* readTime
*
* @param connect_timeout millisecond
*/
public NetConfigBuilder connectionTimeout(int connect_timeout) {
this.connect_timeout = connect_timeout;
return this;
}
/**
* timeout
*
* @param read_timeout millisecond
*/
public NetConfigBuilder readTimeout(int read_timeout) {
this.read_timeout = read_timeout;
return this;
}
/**
* must set Context
*/
public NetConfigBuilder context(Context app) {
this.appContext = app.getApplicationContext();
return this;
}
public NetConfig createNetConfig() {
return new NetConfig(response_cache, response_cache_size, connect_timeout, read_timeout, maxCacheAge, appContext);
}
}
(3)在全局Application中初始化自己配置:
public abstract class NetUtils {
public static NetConfig netConfig;
public static void setNetConfig(NetConfig netConfig){
NetUtils.netConfig = netConfig;
}
public static <T> T createApi(Class<T> clazz, String host){
if(netConfig.context == null)
throw new IllegalArgumentException("must be set Context,use NetUtils.setNetConfig() at once");
return RetrofitUtils.createApi(netConfig.context,clazz,host);
}
}
public class App extends Application{
private static Context context;
//獲取全局context
public static Context getContext(){
return context;
}
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
/**
* net config
*/
final NetConfig netConfig = new NetConfigBuilder()
.context(this)
.responseCacheDir(new File(context.getCacheDir(),"mycache"))
.responseCacheSize(1024 * 1024 * 100)
.readTimeout(2000)
.createNetConfig();
NetUtils.setNetConfig(netConfig);
}
}
二、配置Retrofit和OkHttp
(1)OkHttpUtils可通過設置攔截器等okhttp的初始配置:
public class OkHttpUtils {
private final static File RESPONSE_CACHE = NetUtils.netConfig.RESPONSE_CACHE;
private final static int RESPONSE_CACHE_SIZE = NetUtils.netConfig.RESPONSE_CACHE_SIZE;
private final static int CONNECT_TIMEOUT = NetUtils.netConfig.CONNET_TIMEOUT;
private final static int READ_TIMEOUT = NetUtils.netConfig.READ_TIMEOUT;
private static OkHttpClient singleton;
static OkHttpClient getSingleton(final Context context){
if(singleton == null){
synchronized (OkHttpUtils.class){
if(singleton == null){
singleton = new OkHttpClient().newBuilder()
.cache(new Cache(RESPONSE_CACHE != null?RESPONSE_CACHE:new File(context.getCacheDir(),"defalut_cache"),RESPONSE_CACHE_SIZE))
.addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS)
.readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
.build();
}
}
}
return singleton;
}
private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
if (NetUtil.isNetworkAvailable(App.getContext())) {
int maxAge = 60; // 在線緩存在1分鐘內可讀取
return originalResponse.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
.build();
} else {
int maxStale = 60 * 60 * 24 * 28; // 離線時緩存保存4周
return originalResponse.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
}
}
};
}
(2)RetrofitUtilsze則初始化Retrofit2配置:
public class RetrofitUtils {
private static Retrofit singleton;
static <T> T createApi(Context context, Class<T> clazz, String host){
if(singleton == null){
synchronized (RetrofitUtils.class){
if(singleton == null){
singleton = new Retrofit.Builder()
.baseUrl(host)
.addConverterFactory(GsonConverterFactory.create())
.client(OkHttpUtils.getSingleton(context))
.build();
}
}
}
return singleton.create(clazz);
}
}
三、使用
(1)定義接口,封裝訪問的方法:
public interface AllApi {
@GET("txapi/mvtp/meinv")
Call<GrilBean> getGril(@Header("apikey") String key, @Query("num") int num);
}
(2)調用訪問的方法:
public class ApiUser {
public static AllApi get(){
return NetUtils.createApi(AllApi.class, Constant.url);
}
}
Call<GrilBean> call = ApiUser.get().getGril(Constant.AES_KEY,12);
call.enqueue(new Callback<GrilBean>() {
@Override
public void onResponse(Call<GrilBean> call, Response<GrilBean> response) {
if (response.isSuccessful()) {
GrilBean result = response.body();
//具體操作......
}
}
@Override
public void onFailure(Call<GrilBean> call, Throwable t) {
}
});
四、總結
上面只是給出個初始的封裝,後續可根據其添加所需配置,源碼請看這裏
總之,Retrofit解耦的很徹底:比方說通過註解來配置請求參數,通過工廠來生成CallAdapter,Converter,你可以使用不同的請求適配器(CallAdapter),比方說RxJava,Java8,Guava。你可以使用不同的反序列化工具(Converter),比方說son,protobuff,xml,moshi等等。所以非常推薦使用。