Android:如何从 webview 中远程加载的 html 页面引用资产图像 [英] Android: How to reference asset images from a remotely loaded html page in webview

查看:23
本文介绍了Android:如何从 webview 中远程加载的 html 页面引用资产图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to load/reference images from the app's assets folder from within a HTML page in a WebView. Unlike in most of the examples the HTML page itself is not located in the assets folder but is loaded from a server via http. The background of this question are some performance improvements which should reduce the loading time (and the amount of transferred data) by loading static images directly from the device. I'm not sure if Android has some restrictions here because there's a certain possibility to exploit the app by allowing access to the local file storage from a remotely loaded webpage.

我首先尝试使用 <img src="file:///android_asset/myimage.png"> 加载图像,但失败了(原因很明显).我的下一次尝试是使用 ContentProvider 类并使用 <img src="content://com.myapp.assetcontentprovider/myimage.png"> 引用图像.此 ContentProvider 实现如下:

I first tried to load images using <img src="file:///android_asset/myimage.png"> but this failed (for obvious reasons). My next attempt was to use a ContentProvider class and reference images using <img src="content://com.myapp.assetcontentprovider/myimage.png">. This ContentProvider is implemented as follows:

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 拒绝加载/显示图像.任何想法是否以及如何工作?

When loading the HTML page I can see in the debug log that openFile() is actually triggered from the WebView and it returns a valid ParcelFileDescriptor object but still the image is not displayed. There are no error messages shown in the log which would tell me that WebView refused to load/display the image. Any ideas if and how this could work?

推荐答案

好的,多亏了 mufumbo 的回答,我现在找到了一个可行的技巧,可以在远程加载的 HTML 页面中混合本地资产.使用 WebView 的 loadUrl() 方法加载的页面不会加载与 file:///android_asset/链接的图像...作为一种解决方法,您可以使用 org.apache.http 获取 HTML 页面.client.methods.HttpGet.HttpGet() 然后使用 loadDataWithBaseURL() 将它传递给 WebView.在这种情况下,WebView 将通过 HTTP 加载与 file:///android_asset/链接的资源以及图像和脚本.这是我自定义的 webview 代码:

OK, thanks to mufumbo's answer I now found a working hack to mix local assets in remotely loaded HTML pages. Pages loaded using the WebView's loadUrl() method do not load images linked with file:///android_asset/... As a workaround you can fetch the HTML page using org.apache.http.client.methods.HttpGet.HttpGet() and then pass it to the WebView with loadDataWithBaseURL(). In this case the WebView will load resources linked with file:///android_asset/ as well as images and scripts via HTTP. Here's my customized webview code:

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 中.

Please note that the whole http fetching is wrapped in the home-grown utility class NetUtil.

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

With this class it's possible to render HTML pages from a webserver and have some static resources like images or stylesheets loaded from the app's asset folder in order to improve loading speed and to save bandwidth.

这篇关于Android:如何从 webview 中远程加载的 html 页面引用资产图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆