Bimap实例化研究

一说到Bitmap,所以人都会想到回收,内存溢出等问题,我一直对Bitmap存在的实例化方法不太懂,现在就来看看。

大家都知道有个BitmapFactory类,该类有好多静态方法可以实例化一个Bitmap,看下源码知道, BitmapFactory对Bitmap的实例化最终都归到native层的方法来,我们看下所有的native方法

private static native Bitmap nativeDecodeStream(InputStream is,byte[] storage, Rect padding, Options opts);
private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage, Rect padding, Options opts, boolean applyScale, float scale);
private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,Rect padding, Options opts);
private static native Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts);
private static native Bitmap nativeDecodeAsset(int asset, Rect padding, Options opts,boolean applyScale, float scale);
private static native Bitmap nativeDecodeByteArray(byte[] data, int offset, int length, Options opts);
private static native byte[] nativeScaleNinePatch(byte[] chunk, float scale, Rect pad);
private static native boolean nativeIsSeekable(FileDescriptor fd);

 可以看到主要有这几类

1::nativeDecodeStream , 2:nativeDecodeFileDescriptor,3:nativeDecodeAsset,4:nativeDecodeByteArray     方法可以解析出Bitmap对象

看下各个方法的源码,发现

1:decodeFile,decodeResourceStream,decodeResource这三种得到Bitmap对象的方法最终都会调用方法decodeStream来得到Bitmap对象,而decodeStream会根据图片源的不同,分别调用nativeDecodeStream或者nativeDecodeAsset方法来得到Bitmap对象。

2:decodeByteArray方法会调用nativeDecodeByteArray方法来得到Bitmap对象。

3:decodeFileDescriptor方法会调用nativeDecodeFileDescriptor方法来得到Bitmap对象。

还有一种方法可以实例化一个Bitmap对象,那就是Bitmap.createBitmap(),看下源码:最终会调用

private static Bitmap createBitmap(DisplayMetrics display, int width, int height,
            Config config, boolean hasAlpha) {
        if (width <= 0 || height <= 0) {
            throw new IllegalArgumentException("width and height must be > 0");
        }
        Bitmap bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true);
        if (display != null) {
            bm.mDensity = display.densityDpi;
        }
        if (config == Config.ARGB_8888 && !hasAlpha) {
            nativeErase(bm.mNativeBitmap, 0xff000000);
            nativeSetHasAlpha(bm.mNativeBitmap, hasAlpha);
        } else {
            // No need to initialize it to zeroes; it is backed by a VM byte array
            // which is by definition preinitialized to all zeroes.
            //
            //nativeErase(bm.mNativeBitmap, 0);
        }
        return bm;
    }

 

 最后还是调用native层的代码nativeCreate来创建一个Bitmap对象。

那么Bitmap对象被创建出来后,保存在哪里呢?这个问题,以后再研究。

现在我想做个实验,
实验1:对于一个ImageView显示图片,用xml中的src属性和background属性占用的内存有区别么,

           经实验,发现Heap里面的Allocated分配内存一样大,答案:没区别。

实验2:用xml中的scr属性和用BitmapFactory解析出Bitmap然后在setImageBitmap到ImgeView中

           占用的内存有区别么?经实验,发现Heap里面的Allocated分配内存一样大,答案:没区别。

实验3:给ImageView设置一张小图,然后铺满屏,和给ImageView设置一张大图,铺满屏,

            占用内存有区别么?经实验,发现设置大图的情况下,Heap里面的Allocated分配的内存

            比小图的时候要大的多,答案:设置大图的情况占用内存比设置小图的情况大多了。

实验4:给ImageView设置一张小图,一种铺满屏,一种保持本身大小,占用内存有却别么?

             经实验,占用内存一样大。

 实验5:同一张图片,jpg格式与png格式占用的内存是否相同?同一张图片的意思是只是用PS改了

           下后缀名,jpg图片大小:512K, png图片大小:810K。经实验两张图片占用内存一模一样大。

结论:图片占用内存的大小跟图片显示出来的大小没有关系。一张图片不管你是放大还是缩小,它所占用的内存还是一样大,除非采用采样压缩图片的大小才会影响到图片对内存占用的大小。

猜你喜欢

转载自892848153.iteye.com/blog/2090267