在android webview中使用apk扩展文件中的图像
Posted
技术标签:
【中文标题】在android webview中使用apk扩展文件中的图像【英文标题】:Using images from apk expansion file in android webview 【发布时间】:2012-08-12 18:05:16 【问题描述】:我有一个显示地图的安卓应用。这些地图是高分辨率图像,每张地图切成 100 个图块以保持分辨率。我目前将每张地图放在资产文件夹中的单独文件夹中。由于这使我的 apk 很大,我想将这些图像移动到我的主 apk 扩展文件中。 目前我正在使用以下代码在 webview 中显示图像,以便在 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 解压缩到 sdcard 的情况下使用图像?
【问题讨论】:
你解决过这个问题吗?我有 API 11 及更高版本的解决方案,请参阅***.com/questions/13073594/… 我正在使用 webview.loadUrl,但我已经验证它与 webview.loadDataWithBaseURL 的工作原理相同,但仍然需要 API 10 的解决方案 无法解决这个问题。我目前正在将 obb 提取到 sdcard 并使用那里的图像。 【参考方案1】:由于我的原始答案已降级为评论,因此我将尝试使用新答案进行回复。我不知道为什么,但我现在确实有针对 API 10 及更低版本以及 API 11 及更高版本的解决方案。我将发布代码以澄清。
对于 API 11 及更高版本,只需在您的 webview 客户端中覆盖 ShouldInterceptRequest,
对于 API 10 及以下版本,请使用此 http 侦听器,http://elonen.iki.fi/code/nanohttpd/,
将这两种方法放在一起,对我来说相关的代码是:
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 并将输入流从扩展文件返回到您的文件:
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 );
在顶层某处调用构造函数:
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 方法
我希望这对您有所帮助。这对我来说是一个漫长而痛苦的过程......
【讨论】:
NanoHTTPD 已经弃用了 serve(String, String, Properties...) 取而代之的是 serve(IHTTPSession),但是你可以得到相同的所有属性 - IHTTPSession.getUri() 等等。 【参考方案2】:使用JOBB工具打包扩展文件并使用StorageManager挂载是一个不错的选择。之后,扩展文件中的文件应该可以作为文件系统中的常规文件访问。这种情况下不需要解压扩展文件。
【讨论】:
谢谢!我认为这是一个很好的方法。我写了一篇博客文章,描述了我是如何实现它的:saveme-dot-txt.blogspot.com/2016/06/…以上是关于在android webview中使用apk扩展文件中的图像的主要内容,如果未能解决你的问题,请参考以下文章
Android分享笔记 Android的webview加载本地html本apk内html和远程URL