我正在尝试从WebView中的HTML页面中加载/引用应用程序资源文件夹中的图像.与大多数示例不同,HTML页面本身不在资源文件夹中,而是通过http从服务器加载.此问题的背景是一些性能改进,通过直接从设备加载静态图像,可以减少加载时间(以及传输的数据量).我不确定Android是否有一些限制,因为通过允许从远程加载的网页访问本地文件存储,有一定的可能性来利用该应用程序.
我首先尝试使用加载图像,但失败了(原因很明显).我的下一次尝试是使用
ContentProvider
类和参考图像.此ContentProvider实现如下:
public class AssetContentProvider extends ContentProvider { private static final String URI_PREFIX = "content://com.myapp.assetcontentprovider"; public static String constructUri(String url) { Uri uri = Uri.parse(url); return uri.isAbsolute() ? url : URI_PREFIX + url; } @Override public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException { Log.d("AssetContentProvider", uri.getPath()); try { return getContext().getAssets().openFd(uri.getPath().substring(1)).getParcelFileDescriptor(); } catch (IOException e) { Log.d("AssetContentProvider", "IOException for " + uri.getPath()); throw new FileNotFoundException(); } } // more methods irrelevant for this post }
加载HTML页面时,我可以在调试日志中看到openFile()
实际上是从WebView触发的,它返回一个有效的ParcelFileDescriptor
对象,但仍然没有显示图像.日志中没有显示错误消息,告诉我WebView拒绝加载/显示图像.任何想法是否以及如何运作?
好的,多亏了mufumbo的回答,我现在找到了一个可以在远程加载的HTML页面中混合本地资产的工作黑客.使用WebView loadUrl()
方法加载的页面不会加载与file:/// android_asset/...链接的图像.作为一种解决方法,您可以使用获取HTML页面org.apache.http.client.methods.HttpGet.HttpGet()
,然后将其传递给WebView loadDataWithBaseURL()
.在这种情况下,WebView将通过HTTP加载与file:/// android_asset /以及图像和脚本链接的资源.这是我自定义的webview代码:
public class CustomWebView extends WebView { private String mURL; public void loadUrlWithAssets(final String url) { // copy url to member to allow inner classes accessing it mURL = url; new Thread(new Runnable() { public void run() { String html; try { html = NetUtil.httpGETResponse(mURL); // replace some file paths in html with file:///android_asset/... loadDataWithBaseURL(mURL, html, "text/html", "UTF-8", ""); } catch (IOException e) { Log.e("CustomWebView.loadUrlWithAssets", "IOException", e); } } }).start(); } }
请注意,整个http获取包含在本地实用程序类中NetUtil
.
使用此类,可以从Web服务器呈现HTML页面,并从应用程序的资产文件夹中加载一些静态资源,如图像或样式表,以提高加载速度和节省带宽.