改装+;RxJava无法缓存响应-Android

改装+;RxJava无法缓存响应-Android,android,retrofit,retrofit2,rx-android,okhttp3,Android,Retrofit,Retrofit2,Rx Android,Okhttp3,我在我的项目中使用以下库连接到服务,然后我从服务中获得一个值列表,并将它们填入我的微调器: 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小时更新一次微调器列表 下面

我在我的项目中使用以下库连接到服务,然后我从服务中获得一个值列表,并将它们填入我的微调器:

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小时更新一次微调器列表

下面是我的
API类
,但当我打开应用程序且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)));

如果您试图实现的是刷新数据,而不是避免使用计时器,则固定时间间隔计时器存在一些主要缺点,如电池电量耗尽,其他解决方案(如推送通知)可能更有用,有关这些缺点的详细信息,请参阅:

如果您仍然想使用计时器,这可能会有所帮助:

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); 
解决了我的问题:

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);
    };
}
导入android.content.Context;
导入android.os.Build;
导入android.util.Log;
导入com.bumptech.glide.util.util;
导入com.jakewharton.2.adapter.rxjava2.RxJava2CallAdapterFactory;
导入java.io.File;
导入java.io.IOException;
导入java.security.cert.CertificateException;
导入java.util.concurrent.TimeUnit;
导入javax.net.ssl.HostnameVerifier;
导入javax.net.ssl.SSLContext;
导入javax.net.ssl.SSLSession;
导入javax.net.ssl.SSLSocketFactory;
导入javax.net.ssl.TrustManager;
导入javax.net.ssl.X509TrustManager;
导入xxx.xxx.xxx.tools.Utils;
导入okhttp3.Cache;
导入okhttp3.CacheControl;
进口okhttp3.拦截器;
导入okhttp3.OkHttpClient;
导入okhttp3.请求;
导入okhttp3.响应;
导入okhttp3.logging.HttpLoggingInterceptor;
进口改装2.改装;
进口改装2.converter.gson.GsonConverterFactory;
/**
*由管理员于2017年11月7日创建。
*/
公共类应用程序接口{
私有静态PublicApi改装=空;
私人语境;
PublicPublicAPI getClient(字符串url、上下文上下文、整数值){
OkHttpClient OkHttpClient;
this.context=上下文;
试一试{
//创建不验证证书链的信任管理器
最终TrustManager[]trustAllCerts=新TrustManager[]{
新X509TrustManager(){
@凌驾
public void checkClientTrusted(java.security.cert.X509Certificate[]链,字符串authType)引发CertificateException{
}
@凌驾
public void checkServerTrusted(java.security.cert.X509Certificate[]链,字符串authType)抛出CertificateException{
}
@凌驾
public java.security.cert.X509Certificate[]getAcceptedIssuers(){
返回新的java.security.cert.X509Certificate[]{};
}
}
};
//安装所有信任管理器
最终SSLContext SSLContext=SSLContext.getInstance(“SSL”);
init(null,trustAllCerts,new java.security.SecureRandom());
//使用我们的全信任管理器创建ssl套接字工厂
最终SSLSocketFactory SSLSocketFactory=sslContext.getSocketFactory();
OkHttpClient.Builder=新的OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory,(X509TrustManager)trustAllCerts[0]);
builder.hostnameVerifier(新的hostnameVerifier(){
@凌驾
公共布尔验证(字符串主机名、SSLSession会话){
返回true;
}
});
如果(值==1){
//有关获取日志的信息,请参阅D/OkHttp
HttpLoggingInterceptor logging=新的HttpLoggingInterceptor();
//设置所需的日志级别
logging.setLevel(HttpLoggingInterceptor.Level.Header);
File httpCacheDirectory=新文件(context.getCacheDir(),“responses”);
int cacheSize=10*1024*1024;//10 MiB
Cache Cache=新缓存(httpCacheDirectory,cacheSize);
if(android.os.Build.VERSION.SDK_INT{
Response originalResponse=chain.procedure(chain.request());
字符串cacheControl=originalResponse.header(“缓存控制”);
if(cacheControl==null | | cacheControl.contains(“无存储”)| | cacheControl.contains(“无缓存”)||
cacheControl.contains(“必须重新验证”)| | cacheControl.contains(“最大年龄=0”)){
返回originalResponse.newBuilder()