Android ANR与OOM异常

ANR异常

1.什么是ANR异常?

Application Not Responding,程序无响应

2.原因:

在主线程中做了耗时操作

说到这里,总结一下Android里哪些操作是在主线程中:

(1)Activity的所有生命周期回调

(2)Service默认执行在主线程

(3)BroadCastReceiver的onReceiver回调

(4)没有使用子线程的looper的handler的handlerMessage(),post(Runnable)方法

(5)AsyncTask的回调,除了donInBackground方法,其他都是在主线程

3.如何解决

(1)使用AsyncTask处理耗时操作

(2)使用Thread/HandlerThread提高优先级

(3)使用handler来处理工作线程的耗时任务

(4)Activity的onCreate和onResume回调中尽量避免耗时代码

 

OOM异常

1.什么是OOM异常:

Out of memory 内存溢出

2.原因

当前占用的内存+申请的内存资源超过Dalvik虚拟机的最大内存

(1)cursor没有关闭

(2)调用registerReceiver后没有UnRegisterReceiver

(3)inputStream/outputStream流等没有及时关闭

(4)没有及时调用bitmap.recycle()方法

3.相关概念

内存溢出:OOM

内存抖动:短时间创建大量对象,然后再次释放,触发GC

内存泄露:进程中对象未被引用,但间接引用到其他对象,使GC无法对其起作用

4.解决办法:

(1)有关bitmap

图片显示:比较常见的一种情况是,在显示缩略图时,不要去请求网络加载大图;

及时释放内存:及时调用recycle方法

这里有一个小点:Bitmap的构造方法都是私有的,所有对象的创建都是通过BitmapFactory来创建,而在BitmapFactory创建Bitmap对象时,会调用jni方法,也就是本地方法,所以,给bitmap分配内存时,其实是有两部分的,一个是java内存,还有一部分是C,也就是本地的内存,java内存GC是可以回收的,而C部分的内存,GC是无法回收的,所以必须调用bitmap.recycle()方法来及时释放内存;

 

public void recycle() {
if (!mRecycled && mNativePtr != 0) {
if (nativeRecycle(mNativePtr)) {
// return value indicates whether native pixel object was actually recycled.
// false indicates that it is still in use at the native level and these
// objects should not be collected now. They will be collected later when the
// Bitmap itself is collected.
mNinePatchChunk = null;
}
mRecycled = true;
}
}
private static native boolean nativeRecycle(long nativeBitmap);
图片压缩:对Bitmap进行合理的压缩,这里是用inSampleSize属性进行压缩


BitmapFactory.Options options = new BitmapFactory.Options();

options.inSampleSize = 2;



bm = BitmapFactory.decodeFile(Environment

.getExternalStorageDirectory().getAbsolutePath()

+ "/DCIM/Camera/test.jpg", options);

Log.i("wechat", "压缩后图片的大小" + (bm.getByteCount() / 1024 / 1024)

+ "M宽度为" + bm.getWidth() + "高度为" + bm.getHeight());
inBitmap高级属性:在android3.0开始,系统在BitmapFactory.Options里引入了inBitmap机制来配合缓存机制。如果在载入图片时传入了inBitmap那么载入的图片就是inBitmap里的值。这样可以统一有缓存和无缓存的载入方式。inBitmap属性可以告知bitmap的decode解码器,使用以及存在的内存区域,不用重新分配内存;

捕获异常:捕获的异常是Error属性,oom是一个错误,不是一个异常;

(2)其他方法:

ListView的优化方法:

(A)复用contentView

(B)对于大图控件要采用lru(最近最少使用)机制去缓存bitmap

(C)监听滚动时间,在滑动时不要加载图片;

避免在onDraw方法里面执行对象的创建

posted @ 2022-04-27 19:02  chenxibobo  阅读(187)  评论(0编辑  收藏  举报