博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
安卓学习-Bitmaps与优化
阅读量:7087 次
发布时间:2019-06-28

本文共 14529 字,大约阅读时间需要 48 分钟。

hot3.png

 

 

用到第三方工具类DiskLruCache.java 网上下载  LRU是Least Recently Used 近期最少使用算法

LruCacheUtil.java

package disklrucache; import android.app.ActivityManager; import android.content.Context; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Environment; import android.util.LruCache; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /**  * Created by Administrator on 2016/4/10.  */ //包括内存缓存和磁盘缓存 public class LruCacheUtils {
//单例模式 private static LruCacheUtils lruCacheUtils; private DiskLruCache diskLruCache;//LRU磁盘缓存 private LruCache
lruCache;//LRU内存缓存 private Context context; private LruCacheUtils() {
} public static LruCacheUtils getInstance() {
if (lruCacheUtils == null) {
lruCacheUtils = new LruCacheUtils(); } return lruCacheUtils; } //打开磁盘缓存 public void open(Context context, String disk_cache_subdir, int disk_cache_size) {
try {
this.context = context; //获取当前activity的内存大小 ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); int memoryClass = am.getMemoryClass(); final int cacheSize = memoryClass / 8 * 1024 * 1024;//字节 1/8的内存作为缓存大小(通常) lruCache = new LruCache<>(cacheSize); //open()方法接收四个参数,第一个参数指定的是数据的缓存地址。, //第二个参数指定当前应用程序的版本号 //第三个参数指定同一个key可以对应多少个缓存文件,基本都是传1 //第四个参数指定最多可以缓存多少字节的数据,通常10MB diskLruCache = DiskLruCache.open(getCacheDir(disk_cache_subdir), getAppVersion(), 1, disk_cache_size); } catch (IOException e) {
e.printStackTrace(); } } //添加缓存 public void addBitmapToCache(String url, Bitmap bitmap) {
String key = hashKeyForDisk(url); if (getBitmapFromCache(key) == null) {
System.out.println("key===" + key); System.out.println("bitmap===" + bitmap); lruCache.put(key, bitmap); } } //从缓存中取得缓存的方法 public Bitmap getBitmapFromCache(String url) {
String key = hashKeyForDisk(url); return lruCache.get(key); } //计算位图的采样比例 public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
//获取位图的原宽高 int width = options.outWidth; int height = options.outHeight; System.out.println("width:" + width); System.out.println("height:" + height); //采样比例 int inSampleSize = 1; if (height > reqHeight || width > reqWidth) {
if (width > height) {
//四舍五入,成整数 inSampleSize = Math.round((float) height / (float) reqHeight); } else {
inSampleSize = Math.round((float) width / (float) reqWidth); } } System.out.println("inSampleSize:" + inSampleSize); return inSampleSize; } //位图重新采样 public Bitmap decodeSampledBitmapFromStream(byte[] bytes, int reqWidth, int reqHeight) {
BitmapFactory.Options options = new BitmapFactory.Options(); //先不加载内存 解码 options.inJustDecodeBounds = true; BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options); options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); options.inJustDecodeBounds = false; return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options); } //获取磁盘缓存 public InputStream getDiskCache(String url) {
String key = hashKeyForDisk(url); System.out.println("getDiskCache=" + key); try {
DiskLruCache.Snapshot snapshot = diskLruCache.get(key); System.out.println(snapshot); if (snapshot != null) {
return snapshot.getInputStream(0); } } catch (IOException e) {
} return null; } //下载图片并缓存到内存和磁盘 public void putCache(final String url, final CallBack callBack) {
new AsyncTask
() {
@Override protected Bitmap doInBackground(String... params) {
//传入的是Url String key = hashKeyForDisk(params[0]); System.out.println("key=" + key); //添加 必须得到editor编辑器 DiskLruCache.Editor editor = null; Bitmap bitmap = null; try {
URL url = new URL(params[0]); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(1000 * 30); conn.setConnectTimeout(1000 * 30); ByteArrayOutputStream baos = null; if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); baos = new ByteArrayOutputStream(); byte[] bytes = new byte[1024]; int len = -1; while ((len = bis.read(bytes)) != -1) {
baos.write(bytes, 0, len); } bis.close(); baos.close(); conn.disconnect(); } if (baos != null) {
//第一个参数 使用toByteArray()转成字节数组 bitmap = decodeSampledBitmapFromStream(baos.toByteArray(), 100, 100); //添加到内存的缓存里去 addBitmapToCache(params[0], bitmap); //在添加到磁盘缓存 editor = diskLruCache.edit(key); System.out.println(url.getFile()); //位图压缩后输出(参数:压缩格式,质量(100表示不压缩,30标识压缩70%),磁盘缓存输出流) bitmap.compress(Bitmap.CompressFormat.JPEG, 100, editor.newOutputStream(0)); editor.commit();//提交 } } catch (IOException e) {
try {
editor.abort();//放弃写入 } catch (IOException e1) {
e1.printStackTrace(); } } return bitmap; } @Override protected void onPostExecute(Bitmap bitmap) {
//在UI线程可以调用 super.onPostExecute(bitmap); callBack.response(bitmap); } }.execute(url); } //关闭磁盘缓存 public void close() {
if (diskLruCache != null && !diskLruCache.isClosed()) {
try {
diskLruCache.close(); } catch (IOException e) {
e.printStackTrace(); } } } //刷新磁盘缓存 public void flush() {
if (diskLruCache != null) {
try {
diskLruCache.flush(); } catch (IOException e) {
e.printStackTrace(); } } } //回调接口 public interface CallBack
{
public void response(T entity); } //MD5 计算摘要 ,根据一个字符串,根据MD5计算,计算出16进制的字符串,MD5生成的摘要都是不同的,同一个字符串摘要是一样 public String hashKeyForDisk(String key) {
String cacheKey; try {
final MessageDigest mDigest = MessageDigest.getInstance("MD5"); mDigest.update(key.getBytes()); cacheKey = bytesToHexString(mDigest.digest()); } catch (NoSuchAlgorithmException e) {
cacheKey = String.valueOf(key.hashCode()); } return cacheKey; } private String bytesToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) {
String hex = Integer.toHexString(0xFF & bytes[i]); if (hex.length() == 1) {
sb.append('0'); } sb.append(hex); } return sb.toString(); } //获取版本号 private int getAppVersion() {
try {
return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode; } catch (PackageManager.NameNotFoundException e) {
e.printStackTrace(); } return 1; } //获取缓存目录 private File getCacheDir(String name) {
//name 缓存的名字 //SD卡私有目录,和私有目录 String cachePath = Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED || !Environment.isExternalStorageRemovable() ? context.getExternalCacheDir().getPath() : context.getCacheDir().getPath(); name = cachePath + File.separator + name; System.out.println(name); return new File(name); } }

MainActivity.java

package com.example.administrator.bitmaps; import android.app.Activity; import android.app.ActivityManager; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.util.LruCache; import android.view.View; import android.widget.ImageView; import java.io.InputStream; import disklrucache.LruCacheUtils; public class MainActivity extends Activity {
private ImageView imageView; private ImageView imageView2; private LruCache
lruCache; private LruCacheUtils lruCacheUtils; private static final String DISK_CACHE_SUBDIR="temp"; //10MB 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); imageView2= (ImageView) findViewById(R.id.imageView2); //获取当前activity内存大小 ActivityManager am= (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); int memoryClass=am.getMemoryClass(); final int cacheSize=memoryClass/8*1024*1024;//字节 1/8的内存作为缓存大小(通常) lruCache=new LruCache<>(cacheSize); } public void show2Click(View view) {
String url="http://cdnq.duitang.com/uploads/item/201505/28/20150528200943_sWrYC.jpeg"; loadBitmap(url,imageView2); } //被激活时候 @Override protected void onResume() {
super.onResume(); lruCacheUtils=LruCacheUtils.getInstance(); //打开磁盘缓存 lruCacheUtils.open(this,DISK_CACHE_SUBDIR,DISK_CACHE_SIZE); } @Override protected void onPause() {
super.onPause(); lruCacheUtils.flush(); } @Override protected void onStop() {
super.onStop(); lruCacheUtils.close(); } //加载图片 public void loadBitmap(String url,final ImageView imageView) {//从内存缓存中取图片 Bitmap bitmap=lruCacheUtils.getBitmapFromCache(url); if (bitmap==null) {
//在从磁盘缓存中取 InputStream in=lruCacheUtils.getDiskCache(url); if (in==null) {
//存到磁盘缓存和内存缓存中 lruCacheUtils.putCache(url,new LruCacheUtils.CallBack
() {
@Override public void response(Bitmap entity) {
System.out.println("htto load"); imageView.setImageBitmap(entity); } }); } else {
System.out.println("disk cache"); bitmap=BitmapFactory.decodeStream(in); //磁盘缓存中有,内存缓存中没有 才加到内存缓存中 lruCacheUtils.addBitmapToCache(url,bitmap); imageView.setImageBitmap(bitmap); } } else {
System.out.println("memory cache"); imageView.setImageBitmap(bitmap); } } //添加缓存 public void addBitmapToCache(String key,Bitmap bitmap) {
if (getBitmapFromCache(key)==null) {
lruCache.put(key,bitmap); } } //从缓存中取得缓存的方法 public Bitmap getBitmapFromCache(String key) {
return lruCache.get(key); } public void showClick(View view) {
String key=String.valueOf(R.mipmap.appshare); Bitmap bitmap= getBitmapFromCache(key); if(bitmap==null) {
bitmap= decodeSampledBitmapFromResource(getResources(),R.mipmap.appshare,300,300); addBitmapToCache(key,bitmap); } else {
System.out.println("lruCache中有位图"); } imageView.setImageBitmap(bitmap); } //位图重新采样 public Bitmap decodeSampledBitmapFromResource(Resources res, int resid, int reqWidth, int reqHeight) {
BitmapFactory.Options options = new BitmapFactory.Options(); //先不加载内存 解码 options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resid,options); options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resid,options); } //计算位图的采样比例 public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
//获取位图的原宽高 int width = options.outWidth; int height = options.outHeight; System.out.println("width:"+width); System.out.println("height:"+height); //采样比例 int inSampleSize = 1; if (height > reqHeight || width > reqWidth) {
if (width > height) {
//四舍五入,成整数 inSampleSize = Math.round((float) height / (float) reqHeight); } else {
inSampleSize = Math.round((float) width / (float) reqWidth); } } System.out.println("inSampleSize:"+inSampleSize); return inSampleSize; } }

activity_main.xml

转载于:https://my.oschina.net/xiaofeiandroid/blog/656409

你可能感兴趣的文章
利用UltraISO制作RedhatU盘启动盘
查看>>
什么是高内聚、低耦合?
查看>>
g++编译过程和动态链接库
查看>>
java在线预览txt、word、ppt、execel,pdf代码
查看>>
元素始终居浏览器窗口中间的位置
查看>>
Linux的常用目录(Ubuntu)
查看>>
Completely Uninstall Node.js from Mac OS X
查看>>
如何将Windows XP SP3改成SP2
查看>>
【远程医疗专题】远程医疗论文30篇及解决方案10篇
查看>>
IPSec实验的一些体会
查看>>
c中static作用
查看>>
给初学者的RxJava2.0教程(三)(转)
查看>>
探究ConcurrentHashMap中键值对在Segment[]的下标如何确定
查看>>
Docker学习记录3: 搭建 Private Registry
查看>>
计算机图形学 补 光线跟踪
查看>>
spring整合logback配置文件
查看>>
captive portal
查看>>
mysql基本数据类型(mysql学习笔记三)
查看>>
Laravel踩坑笔记——illuminate/html被抛弃
查看>>
飞秋命令行
查看>>