【问题标题】:Android: How to reference asset images from a remotely loaded html page in webviewAndroid:如何在 webview 中从远程加载的 html 页面引用资产图像
【发布时间】:2010-10-04 11:55:11
【问题描述】:

我正在尝试从 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 拒绝加载/显示图像。任何想法是否以及如何工作?

【问题讨论】:

  • 您是否找到了最初问题的答案(为什么 'file://' 方案 ro 'content://' 不能正常工作)?

标签: android webview assets android-webview


【解决方案1】:

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

【讨论】:

  • 你是如何设法让它对在 web 视图中被点击的链接起作用的?我的只适用于第一页加载。
  • @BradLaney @brotherli 我在哪里可以得到NetUtil
【解决方案2】:

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

String myHTML = "

干杯

【讨论】:

  • 感谢您的回答,但这并不是我正在寻找的解决方案。在我的应用程序中,HTML 页面是使用 myWebView.loadUrl() 从 HTTP 上的 URL 加载的。或者您是否建议使用 org.apache.http 之类的内容加载 HTML 代码,然后使用 loadDataWithBaseURL() 手动将其放入 webview?
  • 你可以这样做。但取决于您下载的 HTML 是使用相对链接还是绝对链接。啊,请确保您的资产以正确的形式命名。 (没有空格和奇怪的字符......)
猜你喜欢
  • 2014-08-29
  • 2013-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-10
  • 2014-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多