/*
* Copyright (c) 2016 咖枯 <kaku201313@163.com | 3772304@qq.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package android.marshon.likequanmintv.librarys.http;
import android.marshon.likequanmintv.base.APP;
import android.marshon.likequanmintv.librarys.http.apiservice.ColumnAPIService;
import android.marshon.likequanmintv.librarys.http.apiservice.LiveAPIService;
import android.marshon.likequanmintv.librarys.http.apiservice.ProfileAPIService;
import android.marshon.likequanmintv.librarys.http.apiservice.RecommendAPIService;
import android.marshon.likequanmintv.librarys.http.converter.JsonConverterFactory;
import android.marshon.likequanmintv.librarys.http.rxjavacalladapter.RxJavaCallAdapterFactory;
import android.marshon.likequanmintv.librarys.utils.LogUtil;
import android.marshon.likequanmintv.librarys.utils.NetUtil;
import android.util.SparseArray;
import java.io.File;
import java.io.IOException;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Retrofit;
/**
* @author 咖枯
* @version 1.0 2016/5/26
*/
public class RetrofitManager {
public static String PLAYERBASE = null;
private final Retrofit mRetrofit;
private String getHost(int hostType) {
if (hostType==HostType.NETEASE_JOKE) {
return PLAYERBASE;
}
return PLAYERBASE;
}
private RecommendAPIService mRecommendAPIService;
private ColumnAPIService mColumnAPIService;
private LiveAPIService mLiveAPIService;
private ProfileAPIService mProfileAPIService;
public RecommendAPIService getRecommendAPIService(){
return mRetrofit.create(RecommendAPIService.class);
}
public ColumnAPIService getColumnAPIService(){
return mRetrofit.create(ColumnAPIService.class);
}
public LiveAPIService getLiveAPIService(){
return mRetrofit.create(LiveAPIService.class);
}
public ProfileAPIService getProfileAPIService(){
return mRetrofit.create(ProfileAPIService.class);
}
/**
* 设缓存有效期为两天
*/
private static final long CACHE_STALE_SEC = 60 * 60 * 24 * 2;
/**
* 查询缓存的Cache-Control设置,为if-only-cache时只查询缓存而不会请求服务器,max-stale可以配合设置缓存失效时间
* max-stale 指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可接收超出超时期指定值之内的响应消息。
*/
private static final String CACHE_CONTROL_CACHE = "only-if-cached, max-stale=" + CACHE_STALE_SEC;
/**
* 查询网络的Cache-Control设置,头部Cache-Control设为max-age=0
* (假如请求了服务器并在a时刻返回响应结果,则在max-age规定的秒数内,浏览器将不会发送对应的请求到服务器,数据由缓存直接返回)时则不会使用缓存而请求服务器
*/
private static final String CACHE_CONTROL_AGE = "max-age=0";
private static volatile OkHttpClient sOkHttpClient;
private static SparseArray<RetrofitManager> sRetrofitManager = new SparseArray<>();
public RetrofitManager(@HostType.HostTypeChecker int hostType) {
mRetrofit = new Retrofit.Builder().baseUrl(getHost(hostType))
.client(getOkHttpClient())
.addConverterFactory(JsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();
}
public static OkHttpClient getOkHttpClient() {
if (sOkHttpClient == null) {
synchronized (RetrofitManager.class) {
Cache cache = new Cache(new File(APP.getContext().getCacheDir(), "HttpCache"),
1024 * 1024 * 100);
if (sOkHttpClient == null) {
sOkHttpClient = new OkHttpClient.Builder().cache(cache)
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.addInterceptor(mRewriteCacheControlInterceptor)
.addNetworkInterceptor(mRewriteCacheControlInterceptor)
.addInterceptor(mLoggingInterceptor)
.build();
}
}
}
return sOkHttpClient;
}
/**
* 云端响应头拦截器,用来配置缓存策略
* Dangerous interceptor that rewrites the server's cache-control header.
*/
private static final Interceptor mRewriteCacheControlInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (!NetUtil.isNetWorkConnectted()) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
LogUtil.d("no network");
}
Response originalResponse = chain.proceed(request);
if (NetUtil.isNetWorkConnectted()) {
//有网的时候读接口上的@Headers里的配置,你可以在这里进行统一的设置
String cacheControl = request.cacheControl().toString();
return originalResponse.newBuilder()
.header("Cache-Control", cacheControl)
.removeHeader("Pragma")
.build();
} else {
return originalResponse.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + CACHE_STALE_SEC)
.removeHeader("Pragma")
.build();
}
}
};
private static final Interceptor mLoggingInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
LogUtil.i(String.format("Sending request %s on %s%n%s", request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
LogUtil.i(String.format(Locale.getDefault(), "Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
return response;
}
};
public static RetrofitManager getInstance() {
return getInstance(HostType.NETEASE_JOKE);
}
public static RetrofitManager getInstance(int hostType) {
RetrofitManager retrofitManager = sRetrofitManager.get(hostType);
if (retrofitManager == null) {
retrofitManager = new RetrofitManager(hostType);
sRetrofitManager.put(hostType, retrofitManager);
return retrofitManager;
}
return retrofitManager;
}
/**
* 根据网络状况获取缓存的策略
*/
public String getCacheControl() {
return NetUtil.isNetWorkConnectted() ? CACHE_CONTROL_AGE : CACHE_CONTROL_CACHE;
}
}