热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

一丶源码见本文二丶演示(略)三丶课程讲解***磁盘缓存工具类*publicclassDiskLruCacheUtils{privatestaticDiskLruCache

一丶源码见本文

二丶演示(略)

三丶课程讲解









/**
* 磁盘缓存 工具类
*/
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() {
@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 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文件夹路径
*


* 安装应用程序下的 私有目录
* 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 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;
}
}



推荐阅读
  • Flowable 流程图路径与节点展示:已执行节点高亮红色标记,增强可视化效果
    在Flowable流程图中,通常仅显示当前节点,而路径则需自行获取。特别是在多次驳回的情况下,节点可能会出现混乱。本文重点探讨了如何准确地展示流程图效果,包括已结束的流程和正在执行的流程。具体实现方法包括生成带有高亮红色标记的图片,以增强可视化效果,确保用户能够清晰地了解每个节点的状态。 ... [详细]
  • 使用Maven JAR插件将单个或多个文件及其依赖项合并为一个可引用的JAR包
    本文介绍了如何利用Maven中的maven-assembly-plugin插件将单个或多个Java文件及其依赖项打包成一个可引用的JAR文件。首先,需要创建一个新的Maven项目,并将待打包的Java文件复制到该项目中。通过配置maven-assembly-plugin,可以实现将所有文件及其依赖项合并为一个独立的JAR包,方便在其他项目中引用和使用。此外,该方法还支持自定义装配描述符,以满足不同场景下的需求。 ... [详细]
  • 网上有很多解决android加载bitmap内存溢出的方法,搜了一圈做下整理总结。项目里需求是拍摄多图之后上传,部分手机会内存溢出。常用一种解决方法:即将载入的图片缩小,这种方式以牺牲图片的质量为代价 ... [详细]
  • Android中Bitmap与Drawable的区别有哪些?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更 ... [详细]
  • 在Android中进行图像处理的任务时,有时我们希望将处理后的结果以图像文件的格式保存在内部存储空间中,本文以此为目的,介绍将Bitmap对象的数据以P ... [详细]
  • 本文介绍如何在 Android 中自定义加载对话框 CustomProgressDialog,包括自定义 View 类和 XML 布局文件的详细步骤。 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 思科IOS XE与ISE集成实现TACACS认证配置
    本文详细介绍了如何在思科IOS XE设备上配置TACACS认证,并通过ISE(Identity Services Engine)进行用户管理和授权。配置包括网络拓扑、设备设置和ISE端的具体步骤。 ... [详细]
  • 在CentOS 7环境中安装配置Redis及使用Redis Desktop Manager连接时的注意事项与技巧
    在 CentOS 7 环境中安装和配置 Redis 时,需要注意一些关键步骤和最佳实践。本文详细介绍了从安装 Redis 到配置其基本参数的全过程,并提供了使用 Redis Desktop Manager 连接 Redis 服务器的技巧和注意事项。此外,还探讨了如何优化性能和确保数据安全,帮助用户在生产环境中高效地管理和使用 Redis。 ... [详细]
  • 属性类 `Properties` 是 `Hashtable` 类的子类,用于存储键值对形式的数据。该类在 Java 中广泛应用于配置文件的读取与写入,支持字符串类型的键和值。通过 `Properties` 类,开发者可以方便地进行配置信息的管理,确保应用程序的灵活性和可维护性。此外,`Properties` 类还提供了加载和保存属性文件的方法,使其在实际开发中具有较高的实用价值。 ... [详细]
  • 本文详细解析了使用C++实现的键盘输入记录程序的源代码,该程序在Windows应用程序开发中具有很高的实用价值。键盘记录功能不仅在远程控制软件中广泛应用,还为开发者提供了强大的调试和监控工具。通过具体实例,本文深入探讨了C++键盘记录程序的设计与实现,适合需要相关技术的开发者参考。 ... [详细]
  • 本文详细介绍了在MySQL中如何高效利用EXPLAIN命令进行查询优化。通过实例解析和步骤说明,文章旨在帮助读者深入理解EXPLAIN命令的工作原理及其在性能调优中的应用,内容通俗易懂且结构清晰,适合各水平的数据库管理员和技术人员参考学习。 ... [详细]
  • 在Android平台中,播放音频的采样率通常固定为44.1kHz,而录音的采样率则固定为8kHz。为了确保音频设备的正常工作,底层驱动必须预先设定这些固定的采样率。当上层应用提供的采样率与这些预设值不匹配时,需要通过重采样(resample)技术来调整采样率,以保证音频数据的正确处理和传输。本文将详细探讨FFMpeg在音频处理中的基础理论及重采样技术的应用。 ... [详细]
  • 在Linux系统中,网络配置是至关重要的任务之一。本文详细解析了Firewalld和Netfilter机制,并探讨了iptables的应用。通过使用`ip addr show`命令来查看网卡IP地址(需要安装`iproute`包),当网卡未分配IP地址或处于关闭状态时,可以通过`ip link set`命令进行配置和激活。此外,文章还介绍了如何利用Firewalld和iptables实现网络流量控制和安全策略管理,为系统管理员提供了实用的操作指南。 ... [详细]
author-avatar
大美妞庄严典雅__
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有