10

我正在尝试从 WebView 的 HTML 页面中加载/引用应用程序资产文件夹中的图像。与大多数示例不同,HTML 页面本身并不位于 assets 文件夹中,而是通过 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 拒绝加载/显示图像。任何想法如果以及如何工作?

4

2 回答 2

6

好的,多亏了 mufumbo 的回答,我现在找到了一个有效的技巧,可以在远程加载的 HTML 页面中混合本地资产。使用 WebView 的loadUrl()方法加载的页面不会加载与 file:///android_asset/ 链接的图像... 作为一种解决方法,您可以使用获取 HTML 页面org.apache.http.client.methods.HttpGet.HttpGet(),然后使用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中。

使用此类,可以从网络服务器渲染 HTML 页面,并从应用程序的资产文件夹加载一些静态资源,如图像或样式表,以提高加载速度并节省带宽。

于 2010-10-28T14:28:34.657 回答
3

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

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

干杯

于 2010-10-21T09:19:49.660 回答