Android 性能优化之图片加载

简介

本文将记录图片加载有关优化以及开源框架的学习和使用,图片加载这一块也是常使用的老难重点了,有必要把这块好好的搞清除,后面可以坦然面对这些问题。

图片存储优化方式

加载一张图片耗费的内存资源 = 宽度 * 高度 * 每个像素占用的内存大小
从这里可以统筹使用: 尺寸压缩,质量压缩,内存重用

Bitmap的内存管理

在Andorid3.0以前,像素数据的支持保存在本地内存地址,bitmap本身是存储在dalvik堆中的,意味着程序员需要调用bitmap.recycle()来对bitmap进行回收。
在Android3.0以后,像素数据和位图都存储在Dalvik堆中,3.0后bitmap不被使用dalvik堆会自动回收。

Android 图标放置的位置

当在分辨率为xxhdi的手机内加载一张图片时,搜索图片进行加载的顺序是 xxhdpi -> xxxhdpi ->nodpi -> xhdpi -> hdpi
也就是说会先从对应分辨率的文件下搜索,如果没有然后由高向低搜索进行加载。记住找到了还会进行缩放。
同一张图片放在不同的资源目录下,会生成不同大小的bitmap

图片加载过程

内存缓存,通过构建hashmap,以图片的url为键,以bitmap为值进行缓存存储
文件缓存 通过url去寻找对应文件中的
如果还没有就去网络请求

图片加载

inJustDecodeBounds = true,在不加载内存的情况下获得图片的宽高
insampleSize 图片的压缩比
通过rgb_565来替换argb_8888可以降低图片内存占用
内存重用:inBitmap 假如已经加载过了就可以进行获取

    /**
     * 加载压缩图片---
     */
    private void loadPic() {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(getResources(),R.drawable.flower,options);

        options.inSampleSize = calculateSampleSize(160,160,options.outWidth,options.outHeight);
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        options.inJustDecodeBounds = false;
        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flower, options);
        mIvOne.setImageBitmap(mBitmap);
    }

   /**
     *
     * @param targetWidth   原始图片的宽
     * @param targetHeight  原始图片的高
     * @param nowWidth      原始图片的宽度
     * @param nowHeight     原始图片的高度
     * @return 返回图片压缩的比率
     */
    private int calculateSampleSize(int targetWidth,int targetHeight,int nowWidth,int nowHeight){
        Log.e("压缩", "未压缩前 宽 = "+nowWidth+",未压缩钱高 = "+nowHeight);
        int result = 1;
        int widthSize = nowWidth%targetWidth == 0? nowWidth/targetWidth:nowWidth/targetWidth+1;
        int heightSize = nowHeight%targetHeight == 0? nowHeight%targetHeight:nowHeight/targetHeight+1;
        int maxSize = Math.max(widthSize,heightSize);
        if (maxSize >= 1){
            result = maxSize;
        }

        if (nowHeight > targetHeight || nowWidth > targetWidth) {
            // 计算出实际宽高和目标宽高的比率
            final int heightRatio = Math.round((float) nowHeight / (float) targetHeight);
            final int widthRatio = Math.round((float) nowWidth / (float) targetWidth);
            // 选择宽和高比率中最小的作为inSampleSize的值,这样可以保证最终生成图片的宽和高
            // 一定都会大于等于目标的宽和高。
            result = heightRatio < widthRatio ? heightRatio : widthRatio;
        }
        Log.e("压缩", "比率 = "+result);
        return result;
    }


    /**
     * 复用已经存在的bitmap
     */
    private void fuyongPic() {
        BitmapFactory.Options options =new  BitmapFactory.Options();
        options.inBitmap = mBitmap;
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flower, options);
        mIvTwo.setImageBitmap(bitmap);
    }

图片加载优化

异步请求 图片放在后台请求
图片缓存 对于列表中的图片进行缓存
懒加载 当图片呈现到可视区域再进行加载

拓展

超大图加载

你可能感兴趣的:(性能优化)