扣丁学堂——Bitmaps与优化(处理较大图片,缓存图片)

来源:互联网 发布:雅马哈p115软件 编辑:程序博客网 时间:2024/05/20 02:28

一丶源码见本文

二丶演示(略)

三丶课程讲解









/** * 磁盘缓存 工具类 */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 0
原创粉丝点击