在android webview中使用apk扩展文件中的图像 [英] Using images from apk expansion file in android webview

查看:22
本文介绍了在android webview中使用apk扩展文件中的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个显示地图的安卓应用.地图是高分辨率图像,每张地图被切成 100 个图块以保持分辨率.我目前将每个地图都放在我的资产文件夹中的一个单独文件夹中.由于这使我的 apk 变得很大,我想将这些图像移动到我的主 apk 扩展文件中.目前,我正在使用以下代码在 webview 中显示图像,以便在 webview 中将图块拼接在一起:

I have an android app that displays maps. The maps are hi-res images sliced to 100 tiles per map to maintain resolution. I currently have each map in a separate folder in my assets folder. As this makes my apk huge, I want to move these images to my main apk expansion file. Currently I am displaying the images in a webview using the following code to stitch the tiles together in the webview:

class ShowMapTask extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... maps) {
        String html = "<html><table cellpadding=\"0\" border=\"0\" cellspacing=\"0.0\">";
        for (int i = 0; i < 10; i++) {
            html += "<tr>";
            for (int j = 0; j < 10; j++)
                html += "<td><img src=\"maps/" + maps[0] + "/slice_" + i
                        + "_" + j + ".png\"></td>";
            html += "</tr>";
        }
        return html + "</table></html>";
    }

    @Override
    protected void onPostExecute(String result) {
        WebView wv = (WebView) context.findViewById(R.id.webView);
        wv.getSettings().setSupportZoom(true);
        wv.getSettings().setBuiltInZoomControls(true);
        wv.getSettings().setUseWideViewPort(true);
        wv.getSettings().setLoadWithOverviewMode(true);
        wv.loadDataWithBaseURL("file:///android_asset/", result,
                "text/html", "utf-8", null);
        super.onPostExecute(result);
    }
}

如何迁移到apk扩展文件?是否可以在不将 obb 解压缩到 SD 卡的情况下使用图像?

How do I migrate to the apk expansion file? Is it possible to use the images without having the unzip the obb to the sdcard?

推荐答案

由于我的原始答案已降级为评论,因此我将尝试使用新答案进行回复.我不知道为什么,但我现在确实有针对 API 10 及以下以及 API 11 及以上的解决方案.我会发布代码来澄清.

I'm going to try responding with a new answer since my original answer was downgraded to a comment. I'm not sure why but I do have a solutions now for API 10 and under as well as API 11 and over. I'll post code to clarify.

对于 API 11 及以上版本,只需在您的 webview 客户端中覆盖 ShouldInterceptRequest,

For API 11 and over simply override ShouldInterceptRequest in your webview client,

对于 API 10 及以下使用此 http 侦听器,http://elonen.iki.fi/code/nanohttpd/,

For API 10 and under use this http listener, http://elonen.iki.fi/code/nanohttpd/,

把这两种方法放在一起,对我来说相关的代码是:

Putting the two approaches together, the relevant pieces of code for me were:

final String assetPrefix = "file:///android_asset/";
final String httpPrefix = "http://localhost:8001";

// for me this part is in onCreateView after the webview settings bit...
{

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
        webView.setWebViewClient(new HoneyCombWebViewClient());
    else
        webView.setWebViewClient(new MyWebViewClient());    

    webViewLoadUrl();
}

private void webViewLoadUrl() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

        curURL = assetPrefix + curFileName;


        webView.loadUrl(curURL);
    }
    else
    {
        curURL = httpPrefix + '/' + curFileName;

        String str = assetFileToString(curFileName);        
        webView.loadDataWithBaseURL(httpPrefix, str, "text/html", "UTF-8", null);    
    }
}

// then for the WebViewClient
private class HoneyCombWebViewClient extends MyWebViewClient {

    public WebResourceResponse shouldInterceptRequest(WebView view, String url)
    {
                    // remove the asset prefix from the url
        String fileName = url.substring(assetPrefix.length() - 1);

                    // ExpansionFiles is the pointer to your ZipResourceFile
        InputStream inputStream = ExpansionFiles.getWebResource(fileName);

        if (url.endsWith("jpg") || url.endsWith("png"))
            return new WebResourceResponse("image/*", "base64", inputStream);

        return super.shouldInterceptRequest(view, url);
    }
}

private class MyWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {

            else if (url.startsWith(httpPrefix)) {

            curURL = url;

            String str = assetFileToString(url.substring(httpPrefix.length() + 1));

            webView.loadDataWithBaseURL(httpPrefix, str, "text/html", "UTF-8", null); 
            return true;
        }
        else if (url.startsWith(assetPrefix)){
            curURL = url;

            view.loadUrl(url);
            return true;        
        }
        // else.....
    }
}

最后,要使用 NanoHTTPD,找到方法 serve 并将输入流从扩展文件返回到您的文件:

Finally, to use NanoHTTPD, find the methods serve and have it return the input stream to your file from the expansion file:

public Response serve( String uri, String method, Properties header, Properties parms, Properties files )
{
    InputStream data = ExpansionFiles.getWebResource(uri);

    String mimeType;
    if (uri.endsWith("jpg") || uri.endsWith("png"))
        mimeType = "base64";
    else if (uri.endsWith("css"))
        mimeType = "text/css";
    else if (uri.endsWith("js"))
        mimeType = "text/javascript";
    else
        mimeType = "text/html";

    return new Response( HTTP_OK, mimeType, data );
}

在顶层某处调用构造函数:

Put in a call to the constructor somewhere at your toplevel:

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
    // this for loading images from expansion file under webview in API 10
    try
    {
        webServer = new NanoHTTPD(8001, new File("."));
    }
    catch( IOException ioe )
    {
        System.err.println( "Couldn't start server:\n" + ioe );
        System.exit( -1 );
    }
}

哦,你需要从 NanoHTTPD 中删除 main 方法

Oh, and you'll need to remove the main method from NanoHTTPD

希望这对您有所帮助.这对我来说是一个漫长而痛苦的过程......

I hope you find this helpful. It was a long and painful process for me....

这篇关于在android webview中使用apk扩展文件中的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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