[置顶] Android使用WebView加载图片防止OutOfMemoryError

        

分类:             Android总结                   571人阅读     评论(0)     收藏     举报    

在Android中, 大图片加载或者处理很容易出来OutOfMemory,也就是内存溢出


    所以在这里就使用WebView来加载大图片,但是WebView不好控制图片显示大小,也就是说

如果图片太大,webview将出一滚动条,图片过小则不可拉伸,极其影响美观。为此,作了些

修改,在一定区域内做一些图片尺寸的压缩。

    主要实现方式:由WebView的父控件居中布局来控制垂直方向的居中,WebView的元素居中

来控制图片的水平居中 ,最终达到图片在屏幕的中间显示。


核心Java代码如下:

  1. private void showImageByWebView(String path){  
  2.         webViewLayout = (LinearLayout) findViewById(R.id.img_webview);  
  3.         webView = new WebView(this);  
  4.           
  5.         String url = "file://"+ path;  
  6.           
  7.         int[] wh = new int[2];  
  8.         int disenty;//屏幕密度  
  9.         WindowManager wManager = this.getWindowManager();  
  10.         DisplayMetrics  disM = new DisplayMetrics();  
  11.         wManager.getDefaultDisplay().getMetrics(disM);    
  12.         disM = this.getResources().getDisplayMetrics();   
  13.         disenty = disM.disenty;  
  14.         wh[0] = dis.widthPixels;  
  15.         Rect outRect = new Rect();  
  16.         webViewLayout.getWindowVisibleDisplayFrame(outRect); //获取状态栏高度  
  17.         int contentHeight = (int) (wh[1] - this.getResources().getDimension(R.dimen.title_height) - outRect.top - 30); //获取webview应该显示的高度,屏幕高度减去标题栏高度和状态栏高度  
  18.           
  19.         BitmapFactory.Options options = new BitmapFactory.Options();  
  20.         options.inJustDecodeBounds = true;   
  21.         BitmapFactory.decodeFile(path, options); // 因为设置了inJustDecodeBounds=true 所以此时返回的 bitmap 为 null,仅取出bitmap的信息,而不把它读到内存  
  22.         options.inJustDecodeBounds = false;    
  23.           
  24.         int bitmapWidth = options.outWidth;   
  25.         int bitmapHeight = options.outHeight;   
  26.           
  27.         String style = "";  
  28.         int[] imgDis = new int[2];  
  29.         int minHeight = getResources().getDimensionPixelSize(R.dimen.loadview_img_minheight);  
  30.           
  31.         //注;由于webview将会设置settings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);表示单列所以宽度适应内容大小,所以宽度大于屏幕而高度小于屏幕时不需要再压缩  
  32.         if(bitmapHeight > (float)contentHeight/disenty){  
  33.             double scale = 0.00f;  
  34.             scale = (double)contentHeight / bitmapHeight;  
  35.             imgDis[0] = (int) (scale * bitmapWidth / (disenty + 0.1));//这里加上了0.1的原因与以上减30一样,webview宽高肯定大于图片内容所显示的宽度,里面还会有padding属性  
  36.             imgDis[1] = (int) (scale * bitmapHeight / (disenty + 0.1));  
  37.             style = "style=\"width: " + imgDis[0] + "px; height: " + imgDis[1] + "px;\"";  
  38.         }else if(bitmapHeight < minHeight){  
  39.             double scale = (double)minHeight/bitmapHeight ;  
  40.             int width = (int) (scale * bitmapWidth);  
  41.             style = "style=\"width: " + width / disenty + "px; height: " + minHeight / disenty + "px;\"";  
  42.         }  
  43.   
  44.         StringBuffer data = new StringBuffer();  
  45.         data.append("<html><center><img src=\"")  
  46.                     .append(url)  
  47.                     .append("\" ")  
  48.                     .append(style)  
  49.                     .append("></center></html>");  
  50.   
  51.         webView.loadDataWithBaseURL(url, data.toString(), "text/html","UTF-8","");  
  52.         webView.setScrollContainer(false);  
  53.         webView.setScrollbarFadingEnabled(false);  
  54.           
  55.         WebSettings settings = webView.getSettings();  
  56.         settings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);  
  57.         settings.setBuiltInZoomControls(false); // 设置显示缩放按钮  
  58.         settings.setSupportZoom(true); //支持缩放  
  59.         //webView.setInitialScale(100);  
  60.           
  61.         // settings.setUseWideViewPort(true); //双击放大,但是在这里如果放大将会有问题  
  62.         // settings.setLoadWithOverviewMode(true);//多窗口预览方式显示  
  63.           
  64.         webView.setBackgroundColor(0x00000000);  
  65.       
  66. //      View zoomControls = webView.getZoomControls();  
  67. //      LayoutParams paramszoom = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);  
  68. //      zoomControls.setLayoutParams(paramszoom);  
  69.           
  70.         LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, Gravity.CENTER);  
  71.         params.width = LayoutParams.WRAP_CONTENT;  
  72.         params.height = LayoutParams.WRAP_CONTENT;  
  73.         webView.setMinimumHeight(500);  
  74.         webViewLayout.addView(webView, params);  
  75.     }  
private void showImageByWebView(String path){
		webViewLayout = (LinearLayout) findViewById(R.id.img_webview);
		webView = new WebView(this);
		
		String url = "file://"+ path;
		
		int[] wh = new int[2];
		int disenty;//屏幕密度
		WindowManager wManager = this.getWindowManager();
		DisplayMetrics  disM = new DisplayMetrics();
		wManager.getDefaultDisplay().getMetrics(disM);  
		disM = this.getResources().getDisplayMetrics();	
		disenty = disM.disenty;
		wh[0] = dis.widthPixels;
		Rect outRect = new Rect();
		webViewLayout.getWindowVisibleDisplayFrame(outRect); //获取状态栏高度
		int contentHeight = (int) (wh[1] - this.getResources().getDimension(R.dimen.title_height) - outRect.top - 30); //获取webview应该显示的高度,屏幕高度减去标题栏高度和状态栏高度
		
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true; 
		BitmapFactory.decodeFile(path, options); // 因为设置了inJustDecodeBounds=true 所以此时返回的 bitmap 为 null,仅取出bitmap的信息,而不把它读到内存
		options.inJustDecodeBounds = false;  
        
		int bitmapWidth = options.outWidth; 
		int bitmapHeight = options.outHeight; 
		
		String style = "";
		int[] imgDis = new int[2];
		int minHeight = getResources().getDimensionPixelSize(R.dimen.loadview_img_minheight);
		
		//注;由于webview将会设置settings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);表示单列所以宽度适应内容大小,所以宽度大于屏幕而高度小于屏幕时不需要再压缩
		if(bitmapHeight > (float)contentHeight/disenty){
			double scale = 0.00f;
			scale = (double)contentHeight / bitmapHeight;
			imgDis[0] = (int) (scale * bitmapWidth / (disenty + 0.1));//这里加上了0.1的原因与以上减30一样,webview宽高肯定大于图片内容所显示的宽度,里面还会有padding属性
			imgDis[1] = (int) (scale * bitmapHeight / (disenty + 0.1));
			style = "style=\"width: " + imgDis[0] + "px; height: " + imgDis[1] + "px;\"";
		}else if(bitmapHeight < minHeight){
			double scale = (double)minHeight/bitmapHeight ;
			int width = (int) (scale * bitmapWidth);
			style = "style=\"width: " + width / disenty + "px; height: " + minHeight / disenty + "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);
		
		WebSettings settings = webView.getSettings();
		settings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
		settings.setBuiltInZoomControls(false); // 设置显示缩放按钮
		settings.setSupportZoom(true); //支持缩放
		//webView.setInitialScale(100);
		
		// settings.setUseWideViewPort(true); //双击放大,但是在这里如果放大将会有问题
		// settings.setLoadWithOverviewMode(true);//多窗口预览方式显示
		
		webView.setBackgroundColor(0x00000000);
	
//		View zoomControls = webView.getZoomControls();
//		LayoutParams paramszoom = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
//		zoomControls.setLayoutParams(paramszoom);
		
		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);
	}


核心布局代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <!-- .....-->  
  8.       
  9.           
  10.     <LinearLayout   
  11.         android:id="@+id/img_webview"  
  12.         android:layout_width="fill_parent"  
  13.         android:layout_height="fill_parent"  
  14.         android:layout_centerInParent="true"  
  15.         android:minHeight="200dip"  
  16.         android:minWidth="200dip"  
  17.         android:gravity="center"  
  18.         android:paddingTop="@dimen/title_normal_height"  
  19.         />  
  20.   
  21. </RelativeLayout>  
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

	<!-- .....-->
    
        
    <LinearLayout 
        android:id="@+id/img_webview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
		android:layout_centerInParent="true"
		android:minHeight="200dip"
        android:minWidth="200dip"
        android:gravity="center"
        android:paddingTop="@dimen/title_normal_height"
        />

</RelativeLayout>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值