最近做的项目里,需要在个人中心面加载很多图片。然后查看了一下友盟上的报错日志,发现好多内存溢出,然后找到错误代码行数,发现好多地方加载本地drawable图片都用的setImageResource,正所谓 ’压死骆驼的最后一根稻草‘ ,无法预料什么时候会触发这个异常,但是既然发现有这个问题还是需要去解决顺便记录一下 😄
java.lang.OutOfMemoryError: Failed to allocate a 1822512 byte allocation with 983600 free bytes and 960KB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:667)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:488)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1082)
at android.content.res.Resources.loadDrawableForCookie(Resources.java:2702)
at android.content.res.Resources.loadDrawable(Resources.java:2603)
at android.content.res.HwResources.loadDrawable(HwResources.java:665)
at android.content.res.Resources.getDrawable(Resources.java:839)
at android.content.Context.getDrawable(Context.java:458)
at android.support.v4.content.ContextCompat.getDrawable(SourceFile:463)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(SourceFile:203)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(SourceFile:191)
at android.support.v7.content.res.AppCompatResources.getDrawable(SourceFile:102)
at android.support.v7.widget.AppCompatImageHelper.setImageResource(SourceFile:86)
at android.support.v7.widget.AppCompatImageView.setImageResource(SourceFile:94)
at com.app.lib.userdetail.activity.DetailsUserActivity.a(SourceFile:1061)
at com.app.lib.userdetail.c.d$1.a(SourceFile:64)
at com.app.lib.userdetail.c.d$1.dataCallback(SourceFile:57)
at com.app.controller.l.dataCallback(SourceFile:15)
at com.app.controller.l.dataCallback(SourceFile:19)
at com.app.model.net.HTTPCaller$CallbackMessage.callback(SourceFile:874)
at com.app.model.net.HTTPCaller$1.handleMessage(SourceFile:74)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:150)
at android.app.ActivityThread.main(ActivityThread.java:5546)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
blog.csdn.net/augfun/arti… 转载来自 augfun 的解决Android加载大图片时内存溢出的问题
InputStream is = this.getResources().openRawResource(R.drawable.pic1);
BitmapFactory.Options options=new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inSampleSize = 10;//width,hight设为原来的十分一
Bitmap btp =BitmapFactory.decodeStream(is,null,options);
if(!bmp.isRecycle() ){
bmp.recycle() //回收图片所占的内存
system.gc() //提醒系统及时回收
}
因此,改用先通过BitmapFactory.decodeStream方法,创建出一个bitmap,再将其设为ImageView的source,decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完成decode,无需再使用java层的createBitmap,从而节省了java层的空间。 如果在读取时加上图片的Config参数,可以跟有效减少加载的内存,从而跟有效阻止抛out of Memory异常 另外,decodeStream直接拿的图片来读取字节码了,不会根据机器的各种分辨率来自动适应,使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相应的图片资源,否则在不同分辨率机器上都是同样大小(像素点数量),显示出来的大小就不对了。
最后,感谢augfun提供的解决方案,如有大佬有更好的方案还请不吝赐教,谢谢🙏🙏