改造+ RxJava不能缓存响应 - Android电子
问题描述:
我从波纹管库在我的项目为连接到服务器上,然后我得到的从服务价值的列表使用,我充满了他们我的微调:改造+ RxJava不能缓存响应 - Android电子
compile 'com.squareup.okhttp3:okhttp:3.6.0'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
问题:如何缓存我的适配器列表48小时,或者我每48小时更新一次我的微调列表服务。
贝娄是我RetrofitApi class
,但呼叫服务当我打开应用程序,我不能缓存48时:
public class RetrofitApi {
private static PublicApi retrofit = null;
public static PublicApi getClient(String url) {
OkHttpClient okHttpClient;
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
okHttpClient = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
request = new Request.Builder()
.cacheControl(new CacheControl.Builder()
.maxAge(2, TimeUnit.DAYS)
.minFresh(48, TimeUnit.HOURS)
.maxStale(48, TimeUnit.HOURS)
.build())
.url(request.url())
.build();
return chain.proceed(request);
}
}).build();
} catch (Exception e) {
throw new RuntimeException(e);
}
retrofit = new Retrofit.Builder()
.baseUrl(url)
.client(okHttpClient)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build().create(PublicApi.class);
return retrofit;
}
}
然后我连接到我的服务像波纹管:
PublicApi publicApi = retrofitApi.getClient("https://xxx.xxx.xxx", context);
mCompositeDisposable.add(publicApi.language("getLanguages")
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(language -> responseLanguage(language, resultListener), language -> errorLanguage(language, resultListener)));
答
解决我的问题:
import android.content.Context;
import android.os.Build;
import android.util.Log;
import com.bumptech.glide.util.Util;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import java.io.File;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import xxx.xxx.xxx.tools.Utils;
import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by admin on 7/11/2017.
*/
public class RetrofitApi {
private static PublicApi retrofit = null;
private Context context;
public PublicApi getClient(String url, Context context, Integer value) {
OkHttpClient okHttpClient;
this.context = context;
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
if (value == 1) {
//For get Log see D/OkHttp
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
// set your desired log level
logging.setLevel(HttpLoggingInterceptor.Level.HEADERS);
File httpCacheDirectory = new File(context.getCacheDir(), "responses");
int cacheSize = 10 * 1024 * 1024; // 10 MiB
Cache cache = new Cache(httpCacheDirectory, cacheSize);
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
okHttpClient = builder.
addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR)
.addInterceptor(OFFLINE_INTERCEPTOR)
.addInterceptor(logging)
.cache(cache)
.build();
} else {
okHttpClient = new OkHttpClient.Builder()
.addNetworkInterceptor(REWRITE_RESPONSE_INTERCEPTOR)
.addInterceptor(OFFLINE_INTERCEPTOR)
.addInterceptor(logging)
.cache(cache)
.build();
}
} else {
okHttpClient = builder.build();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
retrofit = new Retrofit.Builder()
.baseUrl(url)
.client(okHttpClient)
//.client(httpClient.build())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build().create(PublicApi.class);
return retrofit;
}
private Interceptor REWRITE_RESPONSE_INTERCEPTOR = chain -> {
Response originalResponse = chain.proceed(chain.request());
String cacheControl = originalResponse.header("Cache-Control");
if (cacheControl == null || cacheControl.contains("no-store") || cacheControl.contains("no-cache") ||
cacheControl.contains("must-revalidate") || cacheControl.contains("max-age=0")) {
return originalResponse.newBuilder()
.removeHeader("Pragma")
.header("Cache-Control", "public, max-age=" + 60)
.build();
} else {
return originalResponse;
}
};
private Interceptor OFFLINE_INTERCEPTOR = chain -> {
Request request = chain.request();
//if (!Utils.isNetworkAvailable(context)) {
int maxStale = 60 * 60 * 24 * 2; // tolerate 2-days stale
request = request.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
.build();
// }
return chain.proceed(request);
};
}
答
如果你试图实现的是刷新你的数据,而不是你应该避免使用定时器,固定间隔定时器有一些主要缺点,比如电池消耗。其他解决方案,比如推送通知可能更有用,更多关于这些缺点的信息:
如果你仍然想使用计时器比这可能帮助:
scheduleTaskExecutor = Executors.newScheduledThreadPool(5);
//Schedule a task to run at fixed rate scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
// Do stuff here!
runOnUiThread(new Runnable() {
@Override
public void run() {
// Do stuff to update UI here!
Toast.makeText(MainActivity.this, "timer ", Toast.LENGTH_SHORT).show();
}
});
}
}, 0, 48, TimeUnit.HOURS);
你的意思是,以更新的应用程序只针对列表当用户打开它?或者是否需要在48小时周期后显示任何通知? – George
你的意思是只在用户打开它时才更新应用中的列表?是 –