Android Bitmap

本文详细探讨了Android中Bitmap的创建方式,包括构造函数、Bitmap静态方法和BitmapFactory的使用。接着分析了Bitmap内存计算的原理,并通过示例展示了不同资源目录下Bitmap的内存占用。针对Bitmap内存优化,提到了采样率inSampleSize、Matrix缩放以及大图检测策略。最后,讨论了图片缓存框架,如内存中的LruCache和磁盘缓存DiskLruCache,以及网络缓存的重要性。
摘要由CSDN通过智能技术生成

目录

一 应用层Bitmap的创建方式

1.构造函数

2.Bitmap静态方法创建

3.BitmapFactory创建

二 Bitmap内存的计算方式

三 BItmap内存优化

1.采样inSampleSize

2.矩阵Matrix

3.大图检测

四 图片缓存框架

1.内存缓存,LruCache -- 延展开去关于强弱引用

2.磁盘缓存

3.网络缓存



一 应用层Bitmap的创建方式

1.构造函数

frameworks/base/graphics/java/android/graphics/Bitmap.java

    /**
     * Private constructor that must receive an already allocated native bitmap
     * int (pointer).
     */
    // JNI now calls the version below this one. This is preserved due to UnsupportedAppUsage.
    @UnsupportedAppUsage(maxTargetSdk = 28)
    Bitmap(long nativeBitmap, int width, int height, int density,
            boolean requestPremultiplied, byte[] ninePatchChunk,
            NinePatch.InsetStruct ninePatchInsets) {
        this(nativeBitmap, width, height, density, requestPremultiplied, ninePatchChunk,
                ninePatchInsets, true);
    }

    // called from JNI and Bitmap_Delegate.
    Bitmap(long nativeBitmap, int width, int height, int density,
            boolean requestPremultiplied, byte[] ninePatchChunk,
            NinePatch.InsetStruct ninePatchInsets, boolean fromMalloc) {
    }

可以看到它只接受JNI或者bitmap代理调用,不允许应用new它。

2.Bitmap静态方法创建

 方法很多,不过最终调用到的都是

Bitmap bm = nativeCreate(null, 0, width, width, height, config.nativeInt, true,
colorSpace == null ? 0 : colorSpace.getNativeInstance());

3.BitmapFactory创建

 我们这里跟一下BitmapFactory的Bitmap创建流程

frameworks/base/graphics/java/android/graphics/BitmapFactory.java

    public static Bitmap decodeResource(Resources res, int id, Options opts) {
        validate(opts);
        Bitmap bm = null;
        InputStream is = null; 
        
        ...
        final TypedValue value = new TypedValue();
        is = res.openRawResource(id, value);
        bm = decodeResourceStream(res, value, is, null, opts);
        ...
        return bm;
    }

    @Nullable
    public static Bitmap decodeResourceStream(@Nullable Resources res, @Nullable TypedValue value,
            @Nullable InputStream is, @Nullable Rect pad, @Nullable Options opts) {
        validate(opts);
        if (opts == null) {
            opts = new Options();
        }

        if (opts.inDensity == 0 && value != null) {
            final int density = value.density;
            if (density == TypedValue.DENSITY_DEFAULT) {
                opts.inDensity = DisplayMetrics.DENSITY_DEFAULT;
            } else if (density != TypedValue.DENSITY_NONE) {
                //这里density的值如果对应资源目录为hdpi的话,就是240
                opts.inDensity = density;
            }
        }
        //当前屏幕显示密度,我的oppo手机是480
        if (opts.inTargetDensity == 0 && res != null) {
            opts.inTargetDensity = res.getDisplayMetrics().densityDpi;
        }
        
        return decodeStream(is, pad, opts);
    }

这里的重点是opts.inDensity 和opts.inTargetDensity,我们需要根据当前的density进行图片的压缩。我们接着往下看就到了native层

    /**
     * Private helper function for decoding an InputStream natively. Buffers the input enough to
     * do a rewind as needed, and supplies temporary storage if necessary. is MUST NOT be null.
     */
    private static Bitmap decodeStreamInternal(@NonNull InputStream is,
            @Nullable Rect outPadding, @Nullable Options opts) {
        // ASSERT(is !
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值