热门标签 | 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;
}
}



推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 【MicroServices】【Arduino】装修甲醛检测,ArduinoDart甲醛、PM2.5、温湿度、光照传感器等,数据记录于SD卡,Python数据显示,UI5前台,微服务后台……
    这篇文章介绍了一个基于Arduino的装修甲醛检测项目,使用了ArduinoDart甲醛、PM2.5、温湿度、光照传感器等硬件,并将数据记录于SD卡,使用Python进行数据显示,使用UI5进行前台设计,使用微服务进行后台开发。该项目还在不断更新中,有兴趣的可以关注作者的博客和GitHub。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
author-avatar
手机用户2602927805
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有