2017-07-26 131 views
2

我从波纹管库在我的项目为连接到服务器上,然后我得到的从服务价值的列表使用,我充满了他们我的微调:改造+ 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))); 
+0

你的意思是,以更新的应用程序只针对列表当用户打开它?或者是否需要在48小时周期后显示任何通知? – George

+0

你的意思是只在用户打开它时才更新应用中的列表?是 –

回答

0

解决我的问题:

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); 
    }; 
} 
0

如果你试图实现的是刷新你的数据,而不是你应该避免使用定时器,固定间隔定时器有一些主要缺点,比如电池消耗。其他解决方案,比如推送通知可能更有用,更多关于这些缺点的信息:

Scheduling Repeating Alarms

如果你仍然想使用计时器比这可能帮助:

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);