我希望将显示在WebView中的图像缓存一段特定的时间,例如7天,所以我需要将映像缓存保存到磁盘,并将它们从磁盘加载到WebView。
此外,我还需要调整映像的大小,以避免高内存使用率上的WebView;崩溃,因此我在一个名为WebView的阻塞函数中实现了缓存和调整逻辑的大小。
正如Android文档所述,"shouldInterceptRequest“运行在UI以外的线程上,因此我可以在这个函数中进行网络连接,但正如我所看到的,阻塞调用会导致WebView冻结。
函数的行为方式迫使我使用一个阻塞调用,并且我不能传递一个可运行的函数,例如,对于将来的完成。
有什么解决办法吗?
webView.setWebViewClient(new WebViewClient() {
private boolean isImage(String url) {
if (url.contains(".jpg") || url.contains(".jpeg")
|| url.contains(".png")) {
return true;
}
return false;
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if (isImage(url)) {
Bitmap bitmap = ImageUtil.fetchBitmap(url);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 100, bos);
byte[] bitmapdata = bos.toByteArray();
ByteArrayInputStream bs = new ByteArrayInputStream(bitmapdata);
return new WebResourceResponse("image/*", "base64", bs);
}
return null;
}
});--更新--
好的,我改变了逻辑,现在我只是阻止从磁盘读取,并在一个可运行的程序中分别处理网络负载(缓存);当缓存不可用时,"fetchBitmapForWebView";会使网络负载加倍,但是UI现在更响应了。
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
if (isImage(url)) {
Bitmap bitmap = ImageUtil.fetchBitmapForWebView(url);
if (bitmap == null) {
return null;
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 100, bos);
byte[] bitmapdata = bos.toByteArray();
ByteArrayInputStream bs = new ByteArrayInputStream(bitmapdata);
return new WebResourceResponse("image/*", "base64", bs);
}
return null;
}发布于 2015-05-12 20:00:19
一般的原则是,您不应该在shouldInterceptRequest内部执行任何繁重的处理,因为它是一个同步调用(尽管在另一个线程上)。对所有网络请求的调用都是在同一个线程上处理的,因此对一个请求的阻塞也会导致所有其他请求被阻塞。
对于您的用例,我会考虑在应用程序中运行一个小型web服务器,它将完成所有所需的缓存和处理。当然,您还需要重写显示的网页中的所有链接,以便指向本地服务器而不是原始的web服务器,因此在某些情况下可能会很麻烦。但作为一种通用方法,这将极大地帮助卸载繁重的工作和维护本地缓存。
有许多简单的Java web服务器,例如:
https://stackoverflow.com/questions/30180529
复制相似问题