Bitmap的加载与缓存代码分析:

图片的压缩

比如有一张1024*768像素的图像要被载入内存,然而最终你要用到的图片大小其实只有128*96,那么我们会浪费很大一部分内存,这显然是没有必要的,下面是一个实例:

public static int calculateInSampleSize(  
            BitmapFactory.Options options, int reqWidth, int reqHeight) {  
    // Raw height and width of image  
    final int height = options.outHeight;  
    final int width = options.outWidth;  
    int inSampleSize = 1;  
  
    if (height > reqHeight || width > reqWidth) {  
  
        final int halfHeight = height / 2;  
        final int halfWidth = width / 2;  
  
        // Calculate the largest inSampleSize value that is a power of 2 and keeps both  
        // height and width larger than the requested height and width.  
        while ((halfHeight / inSampleSize) > reqHeight  
                && (halfWidth / inSampleSize) > reqWidth) {  
            inSampleSize *= 2;  
        }  
    }  
  
    return inSampleSize;  
}  
为了使用以上的方法,我们在裁剪之前,一定要记得使用inJustDecodeBounder来获取原图大小,在使用完之后,记得将inJustDecodeBounds置为false:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,  
        int reqWidth, int reqHeight) {  
  
    // First decode with inJustDecodeBounds=true to check dimensions  
    final BitmapFactory.Options options = new BitmapFactory.Options();  
    options.inJustDecodeBounds = true;  
    BitmapFactory.decodeResource(res, resId, options);  
  
    // Calculate inSampleSize  
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);  
  
    // Decode bitmap with inSampleSize set  
    options.inJustDecodeBounds = false;  
    return BitmapFactory.decodeResource(res, resId, options);  
}

在剪裁工作做完后,我们就可以将位图载入ImageView了,比如我们设定期望大小为100*100:

mImageView.setImageBitmap(  
    decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

内存缓存技术
另外一种图片缓存的方式就是内存缓存技术。在Android中,有一个叫做LruCache类专门用来做图片缓存处理的。
它有一个特点,当缓存的图片达到了预先设定的值的时候,那么近期使用次数最少的图片就会被回收掉。
步骤:(1)要先设置缓存图片的内存大小,我这里设置为手机内存的1/8,
手机内存的获取方式:int MAXMEMONRY = (int) (Runtime.getRuntime() .maxMemory() / 1024);
(2)LruCache里面的键值对分别是URL和对应的图片
(3)重写了一个叫做sizeOf的方法,返回的是图片数量。

private LruCache<String, Bitmap> mMemoryCache;
private LruCacheUtils() {
if (mMemoryCache == null)
mMemoryCache = new LruCache<String, Bitmap>(
MAXMEMONRY / 8) {
@Override
protected int sizeOf(String key, Bitmap bitmap) {
// 重写此方法来衡量每张图片的大小,默认返回图片数量。
return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
}

@Override
protected void entryRemoved(boolean evicted, String key,
Bitmap oldValue, Bitmap newValue) {
Log.v("tag", "hard cache is full , push to soft cache");

}
};
}
(4)下面的方法分别是清空缓存、添加图片到缓存、从缓存中取得图片、从缓存中移除。
移除和清除缓存是必须要做的事,因为图片缓存处理不当就会报内存溢出,所以一定要引起注意。
public void clearCache() {
if (mMemoryCache != null) {
if (mMemoryCache.size() > 0) {
Log.d("CacheUtils",
"mMemoryCache.size() " + mMemoryCache.size());
mMemoryCache.evictAll();
Log.d("CacheUtils", "mMemoryCache.size()" + mMemoryCache.size());
}
mMemoryCache = null;
}
}

public synchronized void addBitmapToMemoryCache(String key, Bitmap bitmap) {
if (mMemoryCache.get(key) == null) {
if (key != null && bitmap != null)
mMemoryCache.put(key, bitmap);
} else
Log.w(TAG, "the res is aready exits");
}

public synchronized Bitmap getBitmapFromMemCache(String key) {
Bitmap bm = mMemoryCache.get(key);
if (key != null) {
return bm;
}
return null;
}

/**
* 移除缓存
*
* @param key
*/
public synchronized void removeImageCache(String key) {
if (key != null) {
if (mMemoryCache != null) {
Bitmap bm = mMemoryCache.remove(key);
if (bm != null)
bm.recycle();
}
}
}

Android艺术——Bitmap高效加载和缓存代码分析(2)的更多相关文章

  1. Android艺术——Bitmap高效加载和缓存(1)

    通过Bitmap我们可以设计一个ImageLoader,实现应该具有的功能是: 图片的同步加载:图片的异步加载:图片的压缩:内存缓存:磁盘缓存:网络获取: 1.加载 首先提到加载:BitmapFact ...

  2. Android之Bitmap 高效加载

    一张图片(BitMap)占用的内存=图片长度*图片宽度*单位像素占用的字节数 图片格式(Bitmap.Config) 一张100*100的图片占用内存的大小 ALPHA_8 图片长度*图片宽度 100 ...

  3. Android开发之高效加载Bitmap

    一.概述 在Android开发中,我们经常与Bitmap打交道,而对Bitmap的不恰当的操作经常会导致OOM(Out of Memory).这篇文章我们会介绍如何高效地在Android开发中使用Bi ...

  4. Bitmap的加载与缓存

    Android系统中图片一般用Bitmap对象表示,它支持png,jpg等常见格式.通常情况下图片的体积都比较大,单个应用允许使用的内存又是有限的,所以我们需要采取一些手段减少内存占用并提高加载速度. ...

  5. 【第三篇】Volley图片加载之NetworkImageView代码分析

    在Volley的使用之加载图片讲过使用NetWorkImageView进行图片加载的例子,本文着重讲解NetWorkImageView内部是如何实现的,以及Volley这个控件有什么特性.   1,通 ...

  6. Android开发艺术探索》读书笔记 (12) 第12章 Bitmap的加载和Cache

    第12章 Bitmap的加载和Cache 12.1 Bitmap的高速加载 (1)Bitmap是如何加载的?BitmapFactory类提供了四类方法:decodeFile.decodeResourc ...

  7. Android高效加载大图、多图解决方案,有效避免程序OOM

    高效加载大图片 我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有不同的形状.不同的大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小.比如说系统图片库里展示的图片大都是 ...

  8. Android高效加载大图、多图解决方案,有效避免程序OOM(转)

    本篇文章主要内容来自于Android Doc,我翻译之后又做了些加工,英文好的朋友也可以直接去读原文. http://developer.android.com/training/displaying ...

  9. [翻译]Bitmap的异步加载和缓存

    内容概述 [翻译]开发文档:android Bitmap的高效使用 本文内容来自开发文档"Traning > Displaying Bitmaps Efficiently", ...

随机推荐

  1. [日常] imap协议读取邮件

    telnet imap.sina.net 143 A01 LOGIN shihan@appdev.sinanet.com 密码 A02 list "" * //列出邮件夹 * LI ...

  2. Android安全–加强版Smali Log注入

    有的时候我们需要注入smali调用Log输出,打印字符串的值. 比如说: 如果我们要打印下面v1的值. new-instance v1, Ljava/lang/String; const-string ...

  3. 第五课 Css3旋转放大属性,正六边形的绘制

    ---恢复内容开始--- 一.效果 二.知识点 1.background-color: rgba(0,0,0,.4);   (红色.绿色.蓝色.透明度(0-1)) 2.position: absolu ...

  4. Dynamics 365新引入了多选选项集类型字段

    本人微信和易信公众号:微软动态CRM专家罗勇 ,回复276或者20180630可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong.me ...

  5. Scrapped or attached views may not be recycled

    在使用recycleView的时候出现了错误Scrapped or attached views may not be recycled 原因: view没有被recycled,recyclerVie ...

  6. vue.js的手脚架vue-cli项目搭建的步骤

    手脚架是什么? 众所周知,现在的前端项目发展得越渐越大,我们前端程序员要从0开始去搭建一套完整的项目很费时,所以这时候前端工程的手脚架就出现了. 我用得vue-cli也是其中之一,还有其他的我也说不清 ...

  7. iead2018创建JavaWe工程

    菜单栏中 File-> Project,弹出如下界面,选择 Java并勾选 Web Application 填写 Project Name 配置 tomcat 点击右上角的绿色的小锤子,然后打开 ...

  8. 【原】Java学习笔记025 - 内部类

    package cn.temptation; public class Sample01 { public static void main(String[] args) { // 内部类(嵌套类): ...

  9. USB初学(一)---USB-HID的初步认识【转】

    HID是一种USB通信协议,无需安装驱动就能进行交互,在学习HID之前,先来复习一下USB协议的相关内容. USB设备描述符-概述 当插入USB设备后,主机会向设备请求各种描述符来识别设备.那什么是设 ...

  10. 网络编程 单纯UDP通信

    网络编程 单纯UDP通信 1,UDP发送端 2,UDP接收端 UDP发送端: #include <stdio.h> #include <unistd.h> #include & ...