您的当前位置:首页正文

Android使用WebView加载图片防止OutOfMemoryError

2024-11-30 来源:个人技术集锦

在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();
		}
	}


显示全文