引言:
在app的很多實用過程中,經常會出現頻繁的刷新操作,這個刷新不是指去更新ui,而是類似打開界面—關閉界面—再打開—再關閉等。這段過程中,並沒有實質的數據變化,但是這個操作過程中,卻會頻繁的調用接口,初始化數據,然后去刷新UI,當然還有很多其他場景。這類頻繁的無效的數據訪問,無疑會增加網絡請求的次數,給服務器帶來壓力,在弱網環境下,也會帶來卡頓等不好的體驗。
需求分析:
有沒有一種方法,能夠緩存首次成功的數據訪問,然后定個有效期,在這個有效期內,如果還有同一網絡請求,則直接從緩存中獲取返回值。這樣,可以在這個有效期內,減小訪問服務器的次數。當用戶量大的情況下,可以給服務器明顯減負。
解決方案:
經過查找,還真找到一個有效的方案來解決上述問題。
public class NetworkInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); Response response = chain.proceed(request); int maxAge = 60; //有效期 return response.newBuilder() .removeHeader("Pragma") .removeHeader("Cache-Control") .header("Cache-Control", "public, max-age=" + maxAge) .build(); } }
使用方法:
private void testOnlyRequest() throws Exception{ File cacheFile = new File(this.getApplication().getCacheDir(), "caheData"); //設置緩存大小 Cache cache = new Cache(cacheFile, 1024*1024*14); final OkHttpClient client = new OkHttpClient.Builder() .retryOnConnectionFailure(true) .connectTimeout(15,TimeUnit.SECONDS) .addNetworkInterceptor(new NetworkInterceptor()) .cache(cache) .build(); new Thread(new Runnable() { @Override public void run() { Retrofit retrofit= new Retrofit.Builder() .baseUrl("http://fy.iciba.com/") .client(client) .addConverterFactory(GsonConverterFactory.create()) .build(); GetRequest_Interface request = retrofit.create(GetRequest_Interface.class); Call<Translation1> call= request.getCall_1(); Translation1 translation1 = null; try { translation1 = call.execute().body(); translation1.show(); } catch (IOException e) { e.printStackTrace(); } } }).start(); }
補全下代碼:
public interface GetRequest_Interface { // 網絡請求1 @GET("ajax.php?a=fy&f=en&t=zh&w=welcome") Call<Translation1> getCall_1(); }
public class Translation1 { private int status; private content content; private static class content { private String ph_en; private String ph_am; private String ph_en_mp3; private String ph_am_mp3; private String ph_tts_mp3; private String[] word_mean; } //定義 輸出返回數據 的方法 public void show() { Log.d("RxJava", "翻譯內容 = " + content.word_mean[0]); } public void show(Context context){ Toast.makeText(context,"翻譯內容 = " + content.word_mean[0], Toast.LENGTH_SHORT).show(); } }怎么調用就不講了。代碼是最好的老師