Bitmap和OOM笔记

Bitmap获取宽高

Bitmap获取宽高有2种方式,第一种是直接将Bitmap加载进内存中,然后通过测量拿到宽高。

private void getBitmapWH() {
    Bitmap bitmap = BitmapFactory.decodeFile("file/img.jpg");
    int width = bitmap.getWidth();
    int height = bitmap.getHeight() ;
}

然后可以看看decodeFile的源码:

 public static Bitmap decodeFile(String pathName) {
    return decodeFile(pathName, null);
}
 /**
 * Decode a file path into a bitmap. If the specified file name is null,
 * or cannot be decoded into a bitmap, the function returns null.
 *
 * @param pathName complete path name for the file to be decoded.
 * @param opts null-ok; Options that control downsampling and whether the
 *             image should be completely decoded, or just is size returned.
 * @return The decoded bitmap, or null if the image data could not be
 *         decoded, or, if opts is non-null, if opts requested only the
 *         size be returned (in opts.outWidth and opts.outHeight)
 * @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig}
 *         is {@link android.graphics.Bitmap.Config#HARDWARE}
 *         and {@link BitmapFactory.Options#inMutable} is set, if the specified color space
 *         is not {@link ColorSpace.Model#RGB RGB}, or if the specified color space's transfer
 *         function is not an {@link ColorSpace.Rgb.TransferParameters ICC parametric curve}
 */
public static Bitmap decodeFile(String pathName, Options opts) {
    validate(opts);
    Bitmap bm = null;
    InputStream stream = null;
    try {
        stream = new FileInputStream(pathName);
        bm = decodeStream(stream, null, opts);
    } catch (Exception e) {
        /*  do nothing.
            If the exception happened on open, bm will be null.
        */
        Log.e("BitmapFactory", "Unable to decode stream: " + e);
    } finally {
        if (stream != null) {
            try {
                stream.close();
            } catch (IOException e) {
                // do nothing here
            }
        }
    }
    return bm;
}

特意贴出又臭又长、但很有用的注释,注释说会当下面几种情况会返回null:
1、image 数据无法被decode;
2、第二个参数Option不为空,并且Option只想拿到尺寸(通过设置Option的inJustDecodeBounds为true)

 /**
     * If set to true, the decoder will return null (no bitmap), but
     * the <code>out...</code> fields will still be set, allowing the caller to
     * query the bitmap without having to allocate the memory for its pixels.
     */
    public boolean inJustDecodeBounds;

再次看Option里面的inJustDecodeBounds注释,可以看到如果设置该属性为true,则decodeFile不会返回Bitmap,而是返回null,但是返回前会设置一些outXXX的域信息,比如outWidth、outHeight,以便不分配内存就能知道Bitmap的宽高。这就是第二种方式

 private void getBitmapWH() {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;//只拿取尺寸
        Bitmap bitmap = BitmapFactory.decodeFile("file/img.jpg",options);
        //此时拿取的 bitmap == null,上面有说道
        int width = options.outWidth ;
        int height = options.outHeight ;
 }

Android OOM

参考资料:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0920/3478.html

OOM简单来说就是应用所需要的内存,大于系统能分配的内存,这时候应用会崩溃,系统会抛出OutOfMemoryError异常。

如何避免:

1、减小Bitmap对象占用的内存,通过inSampleSize来限制尺寸,通过decode format来选择更小的解码方式
2、及时回收Bitmap对象
3、资源文件重复利用,避免定义多个同样的
4、内存对象重复利用,通过对象池,处理好复用逻辑,降低内存的分配与回收
5、ListView/GridView里面对于ContentView的复用
6、通过LRU机制缓存Bitmap,使用Options.inBitmap属性来制定当前Bitmap占用已经存在的内存区域,而不是重新分配。
7、自定义View中,避免在onDraw等频繁调用的方法里创建对象,这会引起频繁的GC,甚至内存抖动。
8、使用StringBuilder来替换+,由于String是不可变的,所以每次+都会重新创建新对象。
9、避免内存泄露
10、优化内存布局层次,减少内存消耗
11、使用更轻量级的数据结构,比如ArrayMap和SparseArray来替代HashMap等传统数据结构。
12、避免在Android中使用Enum
13、注意监听器的注销,例如调用registerReceiver()后未调用unregisterReceiver()
14、数据库的cursor及时关闭
15、及时关闭读写流
16、谨慎使用static变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值