android--(Bitmap处理较大的位图、缓存位图)

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述


/**
 * 磁盘缓存 工具类
 */
public class DiskLruCacheUtils {
    private static DiskLruCacheUtils diskLruCacheUtils;

    //磁盘缓存插件
    private DiskLruCache diskLruCache;
    private Context context;

    private DiskLruCacheUtils() {
    }

    ;

    /**
     * 单例 提供实例
     *
     * @return
     */
    public static DiskLruCacheUtils getInstance() {
        if (diskLruCacheUtils == null) {
            diskLruCacheUtils = new DiskLruCacheUtils();
        }
        return diskLruCacheUtils;
    }

    /**
     * 磁盘缓存
     *
     * @param context
     * @param disk_cache_subdir :缓存目录
     * @param disk_cache_size   :缓存大小
     */
    public void open(Context context, String disk_cache_subdir, int disk_cache_size) {
        try {
            this.context = context;
            /***
             *  open()方法 接收四个参数,
             *  第一个参数指定的是数据的缓存地址
             *  第二个参数拽定当前应用程序的版本号
             *  第三个参数 指定一个key 可以对应多个缓存文件,基本都是传1
             *  第四个参数指定最多可以缓存多少字节的数据,通常10MB
             */

            diskLruCache = diskLruCache.open(getCacheDir(disk_cache_subdir), getAppVersion(), 1, disk_cache_size);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 根据key 获取 磁盘缓存
     *
     * @param url
     * @return
     */
    public InputStream get(String url) {
        String key = hashkeyForDisk(url);
        try {
            DiskLruCache.Snapshot snapshot = diskLruCache.get(key);
            if (snapshot != null) {
                return snapshot.getInputStream(0);//拿 第几个图片,因为存的时侯是 1
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 磁盘 缓存 存入方法
     *
     * @param url
     */
    public void put(final String url) {
        new AsyncTask<String, Void, Void>() {
            @Override
            protected Void doInBackground(String... params) {

                //计算 md5 的摘要转化为十六进制的字符串,做为存入的键 ,相同的字符串,计算出来是一样
                String key = hashkeyForDisk(params[0]);

                DiskLruCache.Editor editor = null;
                try {
                    URL uri = new URL(params[0]);
                    HttpURLConnection conn = (HttpURLConnection) uri.openConnection();

                    //key作用:存入图片的key值
                    editor = diskLruCache.edit(key);

                    //输入输出缓存流
                    BufferedOutputStream out = new BufferedOutputStream(editor.newOutputStream(0), 8 * 1024);
                    BufferedInputStream in = new BufferedInputStream(conn.getInputStream(), 8 * 1024);

                    byte[] bytes = new byte[1024];
                    int len = -1;

                    //写入磁盘缓存
                    while ((len = in.read(bytes)) != -1) {
                        out.write(bytes, 0, len);
                    }
                    out.close();
                    in.close();
                    editor.commit();
                    conn.disconnect();

                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {

                    try {
                        editor.abort();//放弃写入
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                    e.printStackTrace();
                }

                return null;
            }
        };
    }

    /**
     * 计算字符 MD5 摘要
     *
     * @param key
     * @return
     */
    private String hashkeyForDisk(String key) {

        String cacheKey;
        try {
            final MessageDigest messageDigest = MessageDigest.getInstance("MD5");

            messageDigest.update(key.getBytes());

            //将字符串摘要 计算为 十六进制的 字符串 作为 key
            cacheKey = bytestoHexString(messageDigest.digest());

        } catch (NoSuchAlgorithmException e) {
            cacheKey = String.valueOf(key.hashCode());
            e.printStackTrace();
        }

        return cacheKey;
    }

    /**
     * 计算为 十六进制的 字符串
     *
     * @param digest
     * @return
     */
    private String bytestoHexString(byte[] digest) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < digest.length; i++) {
            String hex = Integer.toHexString(0xFF & digest[i]);
            if (hex.length() == 1) {
                sb.append('0');
            } else {
                sb.append(hex);
            }
        }
        return sb.toString();
    }


    /**
     * 获取缓存 目录
     *
     * @param name :缓存文件
     * @return sdcard 上的 私有目录
     * context.getExternalCacheDir().getPath() :在 mnt/sdcard/android/data/应用程序包/cache文件夹路径
     * <p/>
     * 安装应用程序下的 私有目录
     * context.getCacheDir().getPath() :在 data/data/应用程序包/cache
     */
    private File getCacheDir(String name) {

        String cachePath = Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED
                || !Environment.isExternalStorageRemovable() ?
                context.getExternalCacheDir().getPath() : context.getCacheDir().getPath();

        return new File(cachePath + File.separator + name);


    }


    /**
     * 获取当前应用程序的版本
     */
    public int getAppVersion() {

        try {
            return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        return 1;
    }

}

//本地内存缓存实例
public class MainActivity extends AppCompatActivity {


    private ImageView imageView;

    private LruCache<String, Bitmap> lruCache;

    private DiskLruCacheUtils diskLruCacheUtils;

    //磁盘缓存文件名
    private static final String DISK_CACHE_SUBDIR = "temp";

    //磁盘缓存空间大小
    private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView = (ImageView) findViewById(R.id.imageView);

        //获取当前activity的内存大小
        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        int memoryClass = am.getMemoryClass();

        //计算缓存的大小 字节 8/1 的内存作为缓存大小
        final int cacheSize = memoryClass / 8 * 1024 * 1024;

        lruCache = new LruCache<>(cacheSize);


        diskLruCacheUtils = DiskLruCacheUtils.getInstance();

        diskLruCacheUtils.open(this, DISK_CACHE_SUBDIR, DISK_CACHE_SIZE);


    }


    /**
     * 显示图片
     *
     * @param view
     */
    public void show(View view) {
        String key = String.valueOf(R.mipmap.as);

        Bitmap bitmap = getBitmapCache(key);

        //不缓存中没有时,则再去找
        if (bitmap == null) {
            //获取 采样 缩放的位图
            bitmap = decodeSampleBitmapFromResource(getResources(), R.mipmap.as, 100, 100);

            //图片存入缓存中
            addBitmapCache(key, bitmap);
        } else {
            System.out.print("lruCache:缓存了");
        }

        imageView.setImageBitmap(bitmap);

    }


    //添加到缓存
    public void addBitmapCache(String key, Bitmap bitmap) {
        if (getBitmapCache(key) == null) {
            lruCache.put(key, bitmap);
        }
    }


    //从缓存中 读取对象
    public Bitmap getBitmapCache(String key) {
        return lruCache.get(key);
    }


    /**
     * 位图重样 采样
     *
     * @param res             :资源对象
     * @param resid           :资源的id
     * @param reqWidth        :要显示的宽
     * @param reqHeight:要显示的高
     * @return
     */
    public Bitmap decodeSampleBitmapFromResource(Resources res, int resid, int reqWidth, int reqHeight) {

        BitmapFactory.Options options = new BitmapFactory.Options();

        //只解析边界,不占用内存
        options.inJustDecodeBounds = true;

        //得到边界的 宽 和 高 ,并存入 options中
        BitmapFactory.decodeResource(res, resid, options);

        //得到缩放 值
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

        options.inJustDecodeBounds = false;// false :图片加载到内存中去

        //再解码,这时图片就加载到内存中了,这时的图片是 缩放比例后的图片
        return BitmapFactory.decodeResource(res, resid, options);
    }

    /**
     * 计算位图的 采样比例
     *
     * @param options
     * @param reqWidth  :必须的宽
     * @param reqHeight
     * @return
     */
    public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {

        //获取位图的原大小
        int w = options.outWidth;
        int h = options.outHeight;

        int inSampleSize = 1;

        if (w > reqWidth || h > reqHeight) {
            if (w > h) {
                inSampleSize = Math.round((float) h / (float) reqHeight);
            } else {
                inSampleSize = Math.round((float) w / (float) reqWidth);
            }
        }

        return inSampleSize;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值