Android使用WebView加载图片防止OutOfMemoryError
2013-06-09 16:01
1116 查看
在Android中, 大图片加载或者处理很容易出来OutOfMemory,也就是内存溢出
所以在这里就使用WebView来加载大图片,但是WebView不好控制图片显示大小,也就是说
如果图片太大,webview将出一滚动条,图片过小则不可拉伸,极其影响美观。为此,作了些
修改,在一定区域内做一些图片尺寸的压缩。
主要实现方式:由WebView的父控件居中布局来控制垂直方向的居中,WebView的元素居中
来控制图片的水平居中 ,最终达到图片在屏幕的中间显示。
核心Java代码如下:
private void showImage2WebView(String path, boolean isScale) {
float nowDisenty = disenty;
String url = "file://" + path;
String style = "";
if (isScale) {
if (webScaleImgHeightPx > webImgHeightPx) {
webScaleImgWidthPx = webImgWidthPx;
webScaleImgHeightPx = webImgHeightPx;
} else {
webScaleImgWidthPx = webImgWidthPx + webImgWidthPx / 2;
webScaleImgHeightPx = webImgHeightPx + webImgHeightPx / 2;
}
style = "style=\"width: " + webScaleImgWidthPx + "px; height: " + webScaleImgHeightPx + "px;\"";
} else {
shortContext.setVisibility(View.GONE);
webView = new WebView(this);
Rect outRect = new Rect();
webViewLayout.getWindowVisibleDisplayFrame(outRect);
int contentHeight = (int) (wh[1] - this.getResources().getDimension(R.dimen.title_normal_height) - outRect.top - 30);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options); // 因为设置了inJustDecodeBounds=true 所以此时返回的 bitmap 为 null
options.inJustDecodeBounds = false;
int bitmapWidth = options.outWidth;
int bitmapHeight = options.outHeight;
webImgWidthPx = bitmapWidth;
webImgHeightPx = bitmapHeight;
int[] imgDis = new int[2];
int minHeight = getResources().getDimensionPixelSize(R.dimen.loadview_img_minheight);
double scale = 0.00f;
boolean isScaleByHeight = (double) contentHeight / bitmapHeight < (double) wh[0] / bitmapWidth;
if (bitmapHeight > (float) contentHeight / nowDisenty && isScaleByHeight) {
scale = (double) contentHeight / bitmapHeight;
// if(scale >= 1) scale = 0.9f;
imgDis[0] = (int) (scale * bitmapWidth / (nowDisenty + 0.1));
imgDis[1] = (int) (scale * bitmapHeight / (nowDisenty + 0.1));
webImgWidthPx = imgDis[0];
webImgHeightPx = imgDis[1];
style = "style=\"width: " + webImgWidthPx + "px; height: " + webImgHeightPx + "px;\"";
} else if (bitmapWidth > wh[0]) {
scale = (double) wh[0] / bitmapWidth;
imgDis[0] = (int) (scale * bitmapWidth / (nowDisenty + 0.04));
imgDis[1] = (int) (scale * bitmapHeight / (nowDisenty + 0.04));
webImgWidthPx = imgDis[0];
webImgHeightPx = imgDis[1];
style = "style=\"width: " + webImgWidthPx + "px; height: " + webImgHeightPx + "px;\"";
} else if (bitmapHeight < minHeight) {
scale = (double) minHeight / bitmapHeight;
int width = (int) (scale * bitmapWidth);
webImgWidthPx = (int) (width / nowDisenty);
webImgHeightPx = (int) (minHeight / nowDisenty);
style = "style=\"width: " + webImgWidthPx + "px; height: " + webImgHeightPx + "px;\"";
}
}
StringBuffer data = new StringBuffer();
data.append("<html><center><img src=\"").append(url).append("\" ").append(style).append("></center></html>");
// webView.loadDataWithBaseURL(url, data.toString(), "text/html","UTF-8","");
webView.setScrollContainer(false);
webView.setScrollbarFadingEnabled(false);
webView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
WebSettings settings = webView.getSettings();
settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
settings.setBuiltInZoomControls(false); // 设置显示缩放按钮
settings.setSupportZoom(false); // 支持缩放
// settings.setLoadsImagesAutomatically(true);
// webView.setInitialScale(100);
// settings.setUseWideViewPort(true);
// settings.setLoadWithOverviewMode(true);
webView.setPadding(webView.getPaddingLeft(), webView.getPaddingTop(), webView.getPaddingRight() + 5, webView.getPaddingBottom());
if (!isScale) {
webView.setBackgroundColor(0x00000000);
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, Gravity.CENTER);
params.width = LayoutParams.WRAP_CONTENT;
params.height = LayoutParams.WRAP_CONTENT;
webView.setMinimumHeight(500);
webViewLayout.addView(webView, params);
webView.loadDataWithBaseURL(url, data.toString(), "text/html", "UTF-8", "");
} else {
webView.clearDisappearingChildren();
webView.clearFormData();
webView.clearView();
webView.loadDataWithBaseURL(url, data.toString(), "text/html", "UTF-8", "");
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, Gravity.CENTER);
params.width = LayoutParams.WRAP_CONTENT;
params.height = LayoutParams.WRAP_CONTENT;
//params.height = (int) (webScaleImgHeightPx * disenty);
webViewLayout.removeView(webView);
webViewLayout.addView(webView, params);
webView.invalidate();
webViewLayout.invalidate();
}
}
所以在这里就使用WebView来加载大图片,但是WebView不好控制图片显示大小,也就是说
如果图片太大,webview将出一滚动条,图片过小则不可拉伸,极其影响美观。为此,作了些
修改,在一定区域内做一些图片尺寸的压缩。
主要实现方式:由WebView的父控件居中布局来控制垂直方向的居中,WebView的元素居中
来控制图片的水平居中 ,最终达到图片在屏幕的中间显示。
核心Java代码如下:
private void showImage2WebView(String path, boolean isScale) {
float nowDisenty = disenty;
String url = "file://" + path;
String style = "";
if (isScale) {
if (webScaleImgHeightPx > webImgHeightPx) {
webScaleImgWidthPx = webImgWidthPx;
webScaleImgHeightPx = webImgHeightPx;
} else {
webScaleImgWidthPx = webImgWidthPx + webImgWidthPx / 2;
webScaleImgHeightPx = webImgHeightPx + webImgHeightPx / 2;
}
style = "style=\"width: " + webScaleImgWidthPx + "px; height: " + webScaleImgHeightPx + "px;\"";
} else {
shortContext.setVisibility(View.GONE);
webView = new WebView(this);
Rect outRect = new Rect();
webViewLayout.getWindowVisibleDisplayFrame(outRect);
int contentHeight = (int) (wh[1] - this.getResources().getDimension(R.dimen.title_normal_height) - outRect.top - 30);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options); // 因为设置了inJustDecodeBounds=true 所以此时返回的 bitmap 为 null
options.inJustDecodeBounds = false;
int bitmapWidth = options.outWidth;
int bitmapHeight = options.outHeight;
webImgWidthPx = bitmapWidth;
webImgHeightPx = bitmapHeight;
int[] imgDis = new int[2];
int minHeight = getResources().getDimensionPixelSize(R.dimen.loadview_img_minheight);
double scale = 0.00f;
boolean isScaleByHeight = (double) contentHeight / bitmapHeight < (double) wh[0] / bitmapWidth;
if (bitmapHeight > (float) contentHeight / nowDisenty && isScaleByHeight) {
scale = (double) contentHeight / bitmapHeight;
// if(scale >= 1) scale = 0.9f;
imgDis[0] = (int) (scale * bitmapWidth / (nowDisenty + 0.1));
imgDis[1] = (int) (scale * bitmapHeight / (nowDisenty + 0.1));
webImgWidthPx = imgDis[0];
webImgHeightPx = imgDis[1];
style = "style=\"width: " + webImgWidthPx + "px; height: " + webImgHeightPx + "px;\"";
} else if (bitmapWidth > wh[0]) {
scale = (double) wh[0] / bitmapWidth;
imgDis[0] = (int) (scale * bitmapWidth / (nowDisenty + 0.04));
imgDis[1] = (int) (scale * bitmapHeight / (nowDisenty + 0.04));
webImgWidthPx = imgDis[0];
webImgHeightPx = imgDis[1];
style = "style=\"width: " + webImgWidthPx + "px; height: " + webImgHeightPx + "px;\"";
} else if (bitmapHeight < minHeight) {
scale = (double) minHeight / bitmapHeight;
int width = (int) (scale * bitmapWidth);
webImgWidthPx = (int) (width / nowDisenty);
webImgHeightPx = (int) (minHeight / nowDisenty);
style = "style=\"width: " + webImgWidthPx + "px; height: " + webImgHeightPx + "px;\"";
}
}
StringBuffer data = new StringBuffer();
data.append("<html><center><img src=\"").append(url).append("\" ").append(style).append("></center></html>");
// webView.loadDataWithBaseURL(url, data.toString(), "text/html","UTF-8","");
webView.setScrollContainer(false);
webView.setScrollbarFadingEnabled(false);
webView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
WebSettings settings = webView.getSettings();
settings.setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
settings.setBuiltInZoomControls(false); // 设置显示缩放按钮
settings.setSupportZoom(false); // 支持缩放
// settings.setLoadsImagesAutomatically(true);
// webView.setInitialScale(100);
// settings.setUseWideViewPort(true);
// settings.setLoadWithOverviewMode(true);
webView.setPadding(webView.getPaddingLeft(), webView.getPaddingTop(), webView.getPaddingRight() + 5, webView.getPaddingBottom());
if (!isScale) {
webView.setBackgroundColor(0x00000000);
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, Gravity.CENTER);
params.width = LayoutParams.WRAP_CONTENT;
params.height = LayoutParams.WRAP_CONTENT;
webView.setMinimumHeight(500);
webViewLayout.addView(webView, params);
webView.loadDataWithBaseURL(url, data.toString(), "text/html", "UTF-8", "");
} else {
webView.clearDisappearingChildren();
webView.clearFormData();
webView.clearView();
webView.loadDataWithBaseURL(url, data.toString(), "text/html", "UTF-8", "");
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, Gravity.CENTER);
params.width = LayoutParams.WRAP_CONTENT;
params.height = LayoutParams.WRAP_CONTENT;
//params.height = (int) (webScaleImgHeightPx * disenty);
webViewLayout.removeView(webView);
webViewLayout.addView(webView, params);
webView.invalidate();
webViewLayout.invalidate();
}
}
相关文章推荐
- [置顶] Android使用WebView加载图片防止OutOfMemoryError
- Android中 加载一张大图片Caused by: java.lang.OutOfMemoryError
- 【Android】Bitmap加载图片错误 java.lang.OutOfMemoryError: bitmap size exceeds VM budget
- android利用Bitmap加载图片所遇到的一个奇怪的OOM问题java.lang.OutOfMemoryError
- 显示图片列表时出现异常java.lang.OutOfMemoryError或android.view.InflateException: Binary XML file line #98: Error
- Android 加载图片内存溢出解决方法 (java.lang.outOfMemoryError:....)
- Android加载大图片不OutOfMemoryError
- 【Android】Bitmap加载图片错误 java.lang.OutOfMemoryError: bitmap size exceeds VM budget
- Android 加载大图片是出现的 OutOfMemoryError问题
- android开发步步为营之50:android关于加载大图片java.lang.OutOfMemoryError错误的解决
- 彻底解决Android因加载多个大图引起的OutOfMemoryError,内存溢出的问题
- android webView 图片加载不出来 后台报错Uncaught TypeError: Cannot call method 'getElementsByTagName' of null
- Android学习 ——引用图片导致内存溢出java.lang.OutOfMemoryError
- Android webView 加载网页时,使用本地图片替换网页内的图片
- 用Bitmap加载图片资源时,报错java.lang.OutOfMemoryError: bitmap size exceeds VM budget的解决办法
- Android加载图片导致内存溢出(Out of Memory异常)
- Android加载图片导致内存溢出(Out of Memory异常)
- Android GridView异步加载图片和加载大量图片时出现Out Of Memory问题
- android 加载图片轻松避免OOM(out of memory)
- android加载图片时避免出现OOM(OutOfMemory)