Android的:如何从web视图一个远程加载HTML页面中引用的资产图像视图、图像、加载、资产

2023-09-04 03:57:24 作者:岁月你慢些走

我想在web视图从一个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 =文件:///android_asset/myimage.png> 但是这个失败(原因很明显) 。我的下一个尝试是使用的ContentProvider 类和使用参考图像< IMG SRC =内容://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页面混合本地资产。使用web视图的使用loadURL()方法不加载与文件链接的图像载入的页面:/// android_asset / ...作为一种解决方法,你可以获取使用HTML页面 org.apache.http.client.methods.HttpGet.HttpGet()键,然后将其与 loadDataWithBaseURL()传递给web视图。在这种情况下,web视图将加载与文件链接的资源:/// android_asset /以及图像和脚本通过HTTP。这里是我的自定义的WebView code:

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.