android - 重磅:实现了对于js/css/png等文件的缓存. 只要能拦截,就可以缓存!
访问量: 2642
啥也不说了,直接上代码.核心方法是: queryFromCacheIfPossible (代码不完整,仅仅是个描述作用. TODO: 公开成 github项目)
@Override public void onPageStarted(WebView view, String url, Bitmap favicon) { Log.d(TAG, "onPageStarted, 触发的url是====" + url); super.onPageStarted(view, url, favicon); } @RequiresApi(api = Build.VERSION_CODES.KITKAT) @Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) { Log.d(TAG, "shouldInterceptRequest, 触发的url是====" + url); if(url.contains("__webpack_hmr")) { Log.d(TAG, "return empty response on __webpack_hmr"); return new WebResourceResponse(null,null, null); } if( shouldQueryFromCache(url)) { return queryFromCacheIfPossible(url); } return super.shouldInterceptRequest(view, url); } public boolean shouldQueryFromCache(String url) { // endsWith 方法貌似不支持 a | b 这样的表达式...只好这么写了 ... Orz boolean result = url.endsWith("png") || url.endsWith("PNG") || url.endsWith("jpg") || url.endsWith("JPG") || url.endsWith("jpeg") || url.endsWith("JPEG") || url.endsWith("css") || url.endsWith("css.map") || url.endsWith("js") || url.endsWith("js.map"); return result; } /** * 核心方法. 根据url, 向远程发起请求, 并保存文件到本地. */ @RequiresApi(api = Build.VERSION_CODES.KITKAT) public WebResourceResponse queryFromCacheIfPossible(final String url) { Log.d(TAG, "== in queryFromCacheIfPossible, url: "+ url); String webResourceLocalFileName = getWebResourceLocalFileName(url); File webResourceCacheFile = new File( getContext().getCacheDir(), webResourceLocalFileName); if(webResourceCacheFile.exists()){ Log.d(TAG, "== hit the cache: " + webResourceLocalFileName); try{ FileInputStream fileInputStream = new FileInputStream(new File(getContext().getCacheDir(), webResourceLocalFileName)); return new WebResourceResponse(getMimeTypeBySuffix(url), "utf-8", fileInputStream); }catch (IOException e){ e.printStackTrace(); return new WebResourceResponse(getMimeTypeBySuffix(url), "utf-8", null); } }else{ Log.d(TAG, "== NOT hit the cache: " + webResourceLocalFileName); OkHttpClient okHttpClient = new OkHttpClient(); Request request = new Request.Builder() .url(url) .build(); try { Response response = okHttpClient.newCall(request).execute(); writeHttpResponseToFile(url, response); Log.d(TAG, "== mime : " + getMimeTypeBySuffix(url)); // 这段代码可以让图片正常显示! // js: doing... FileInputStream fileInputStream = new FileInputStream(new File(getContext().getCacheDir(), webResourceLocalFileName)); return new WebResourceResponse(getMimeTypeBySuffix(url), "utf-8", fileInputStream); }catch (IOException e){ Log.e(TAG, "== got IOException"); e.printStackTrace(); return new WebResourceResponse(getMimeTypeBySuffix(url), "utf-8", null); } } } public String getWebResourceLocalFileName(String url){ String[] temp = url.split("/"); String fileName = temp[temp.length - 1]; return fileName; } public String writeHttpResponseToFile(String url, Response response){ String fileName = getWebResourceLocalFileName(url); Log.d(TAG, "== in writeHttpResponseToFile"); // TODO Write file ... File file = new File(getContext().getCacheDir(), fileName); try{ BufferedSink bufferedSink = Okio.buffer(Okio.sink(file)); bufferedSink.writeAll(response.body().source()); bufferedSink.close(); }catch(Exception e){ Log.e(TAG, "== got error in writeHttpResponseToFile"); e.printStackTrace(); } return fileName; } public String getMimeTypeBySuffix(String url){ String result = ""; if(url.endsWith("png") || url.endsWith("PNG")){ result = "image/png"; }else if (url.endsWith("jpg") || url.endsWith("JPG") || url.endsWith("jpeg") || url.endsWith("JPEG")){ result = "image/jpg"; }else if (url.endsWith("css") || url.endsWith("css.map")){ result = "text/css"; }else if (url.endsWith("js") ||url.endsWith(".js.map") ){ result = "application/javascript"; }else{ result = "text/plain"; } return result; }