Android:如何在webview中从远程加载的html页面引用资产图像

时间:2010-10-04 11:55:11

标签: android webview assets android-webview

我正在尝试从WebView中的HTML页面中加载/引用应用程序资源文件夹中的图像。与大多数示例不同,HTML页面本身不在资源文件夹中,而是通过http从服务器加载。此问题的背景是一些性能改进,通过直接从设备加载静态图像,可以减少加载时间(以及传输的数据量)。我不确定Android是否有一些限制,因为通过允许从远程加载的网页访问本地文件存储,有可能利用该应用程序。

我首先尝试使用<img src="file:///android_asset/myimage.png">加载图片,但这失败了(原因很明显)。我的下一次尝试是使用ContentProvider类并使用<img src="content://com.myapp.assetcontentprovider/myimage.png">引用图像。 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拒绝加载/显示图像。任何想法是否以及如何起作用?

2 个答案:

答案 0 :(得分:6)

好的,多亏了mufumbo的回答,我现在发现了一个可以在远程加载的HTML页面中混合本地资产的工作黑客。使用WebView的loadUrl()方法加载的页面不会加载与file:/// android_asset / ...链接的图像。作为一种解决方法,您可以使用org.apache.http.client.methods.HttpGet.HttpGet()获取HTML页面,然后将其传递给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页面,并从应用程序的资产文件夹中加载一些静态资源,如图像或样式表,以提高加载速度和节省带宽。

答案 1 :(得分:3)

这就是我在java部分的做法:

String myHTML =“&lt; img src = \”file:///android_asset/myimage.jpg \“”; myWebView.loadDataWithBaseURL(“file:/// android_asset /”,myHTML,“text / html”,“UTF-8”,“”);

欢呼声