java.lang.OutOfMemoryError问题与heap获取

java.lang.OutOfMemoryError

atandroid.graphics.BitmapFactory.nativeDecodeAsset(Native Method)

atandroid.graphics.BitmapFactory.decodeStream(BitmapFactory.java:502)

atandroid.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:355)

这是一个内存溢出的错误,总感觉项目的apk文件并不大,怎么会出现内存以溢出。

通常是因为加载分辨率比较大的图片,图片的本身大小不一定大。

图片的分辨率比较大,例如大小为300KB,分辨率为1280*1920的一张图片,300KB其实并不算大,但是android在加载图片时并不是看图片真实大小大小,而是看图片的分辨率,在实际加载时android认为该图片大小为9MB,在这我并没有胡说,在android中每一种颜色的每一个像素点为1字节,1280*1920/1024=2400KB位图图片是RGB三色,在Android则是ARGB,A为透明度,RGB就不多说了。2400*4/1024=9.375MB,也就是说该图片在加载时占用了9MB的内存。一张就是9MB,多加载几张,再加上其他内容,可想而知,这个app的所占运行不就很大了。

仔细算下来也不过几十兆,现在手机的RAM至少512MB了,区区几十兆算的了什么,这也不可能产生内存溢出。其实在android中,这些运存并不是让应用程序随意使用的,android对每一个进程所占用的运存是有上限的,即heap是有上限的。如果手机或模拟器的heap比较大,java.lang.OutOfMemoryError这个运行时期的异常出现的就比较少,但无论heap有多大,一个手机的heap是固定的。G1:16MB,Droid:24MB,Nexus One:32MB,Xoom:48MB等。

现在已经明白java.lang.OutOfMemoryError出现的原因了

那么如何解决?

解决方法也很简单就是图片缩放显示。

 

//获取屏幕大小

   WindowManager manager = getWindowManager();

                   Point point = new Point();

                   manager.getDefaultDisplay().getSize(point);

                   mScreenWidth = point.x;

                   mScreenHight = point.y;

 

                   BitmapFactory.Options options = new Options();

                   // 不解析图片

                   options.inJustDecodeBounds = true;

                   BitmapFactory.decodeResource(getResources(),mImages[0], options);

                   int imgWidth = options.outWidth;

                   int imgHeigth = options.outHeight;

                   int scaleWidth = imgWidth / mScreenWidth;

                   int scaleHeight = imgHeigth / mScreenHight;

                   int scale = scaleWidth > scaleHeight ? scaleWidth : scaleHeight;

                   ActivityManager am =(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

                   int memory = am.getMemoryClass();

                   if (memory < 32)

                            scale = scale > 2 ? scale : 2;

                   options.inSampleSize = scale;

                   for (int i = 0; i < mImages.length; i++) {

                            ImageView imageView = new ImageView(GuideActivity.this);

                            // 解析图片

                            options.inJustDecodeBounds = false;

                            Bitmap bitmap = BitmapFactory.decodeResource(getResources(),

                                               mImages[i], options);

                            imageView.setImageBitmap(bitmap);

                            mList.add(imageView);

                   }

         

至于如何获取heap的大小也很简单:

ActivityManageram=(ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);

int memorySize = am.getMemoryClass();

memorySize比较小时在缩放图片,可保持图片的清晰度,但会增加响应时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值