本篇文章为大家展示了Android中怎么实现图片三级缓存,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。
1、内存缓存,android为我们提供LruCache=其中维护着一个LinkedHashMap。LruCache可以用来存储各种类型的数据,我们设置它的大小,一般是系统最大存储空间的1/8.
public class MemoryCacheUtil {
private LruCache<String, Bitmap> lruCache;
public MemoryCacheUtil(){
int maxSize = (int) (Runtime.getRuntime().maxMemory()/8);
// 一般获取当前应用的最大内存的1/8作为LruCache的容量
lruCache = new LruCache<String, Bitmap>(maxSize){
// 设置当前添加的图片的大小
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes()*value.getHeight();
}
};
}
// 从内存缓存取图片
public Bitmap getBitmap(String url){
return lruCache.get(url);
}
// 在内存缓存存图片
public void putBitmap(String url,Bitmap bitmap){
lruCache.put(url, bitmap);
}
}
2、本地缓存根据url,获取本地文件,把url进行md5加密,作为文件名,保证文件的正确性.
MD5加密工具类
public class MD5Encoder {
public static String encode(String string) throws Exception {
byte[] hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
StringBuilder hex = new StringBuilder(hash.length * 2);
for (byte b : hash) {
if ((b & 0xFF) < 0x10) {
hex.append("0");
}
hex.append(Integer.toHexString(b & 0xFF));
}
return hex.toString();
}
}
本地缓存
public class LocalCacheUtil {
private String CACHE_URl;
private MemoryCacheUtil memoryCacheUtil;
public LocalCacheUtil(MemoryCacheUtil memoryCacheUtil){
// 初始化本地存储的路径
CACHE_URl = Environment.getExternalStorageDirectory().getAbsoluteFile()+ "/test";
this.memoryCacheUtil = memoryCacheUtil;
}
// 从本地sdcard取图片
public Bitmap getBitmap(String url){
// 根据url,获取本地文件,把url进行md5加密,作为文件名
try {
String fileName = MD5Encoder.encode(url);
File file = new File(CACHE_URl, fileName);
if(file.exists()){// 判断当前文件是否存在
// 把当前文件转换成Bitmap对象
Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
// 需往内存中存一份
memoryCacheUtil.putBitmap(url, bitmap);
return bitmap;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 往本地存图片的方法
public void saveBitmap(String url,Bitmap bitmap){
try {
String fileName = MD5Encoder.encode(url);
File file = new File(CACHE_URl, fileName);
// 判断是否需要创建父目录
File parentFile = file.getParentFile();
if(!parentFile.exists()){
parentFile.mkdirs();
}
// 把Bitmap对象保存到文件中 质量越高压缩速度越慢
OutputStream stream = new FileOutputStream(file);
bitmap.compress(CompressFormat.PNG, 100, stream);//第一个参数可以设置图片格式,第二个图片压缩质量,第三个为图片输出流
} catch (Exception e) {
e.printStackTrace();
}
}
}
3、网络缓存使用异步加载AsyncTask,使用其有二种原因:
1.doInBackground运行在子线程,做网络请求耗时操作,避免主线程堵塞;
2.onPreExecute和onPostExecute便于更新UI提高用户体验。
public class NetCacheUtil {
private MemoryCacheUtil memoryCacheUtil;
private LocalCacheUtil localCacheUtil;
private ListView lv_image_list;
public NetCacheUtil(MemoryCacheUtil memoryCacheUtil,LocalCacheUtil localCacheUtil){
this.memoryCacheUtil = memoryCacheUtil;
this.localCacheUtil = localCacheUtil;
}
public void display(ImageView imageView ,String url, ListView lv_image_list){
this.lv_image_list = lv_image_list;
new MyAsyncTask(imageView).execute(new Object[]{url,imageView});
}
class MyAsyncTask extends AsyncTask<Object, Void, Bitmap>{
private ImageView imageView;
private int position;
public MyAsyncTask(ImageView imageView2) {
position = (Integer) imageView2.getTag();
}
// 运行在主线程,做准备操作,在doInBackground之前,可以放置加载条提高用户体验
@Override
protected void onPreExecute() {
super.onPreExecute();
}
// 运行在子线程,做耗时操作
@Override
protected Bitmap doInBackground(Object... params) {
// 获取url,下载图片
String url = (String) params[0];
// 获取ImageView
imageView = (ImageView) params[1];
try {
// 下载图片
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.connect();// 连接网络
// 获取响应码
int resCode = conn.getResponseCode();
if(resCode==200){// 访问成功
// 把服务器返回的输入流转换成Bitmap对象
Bitmap bitmap = BitmapFactory.decodeStream(conn.getInputStream());
// 保存到本地和内存
memoryCacheUtil.putBitmap(url, bitmap);
localCacheUtil.saveBitmap(url, bitmap);
return bitmap;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 运行在主线程,更新界面,在doInBackground之后
@Override
protected void onPostExecute(Bitmap result) {
// 判断线程开始时,那个位置是否还在Listview中
ImageView view = (ImageView) lv_image_list.findViewWithTag(position);
if(view!=null){
view.setImageBitmap(result);
}
super.onPostExecute(result);
}
}
}
4、封装三级缓存形成ImageUtil,因内存缓存中取速度较快,所以先从内存缓存中取,取不到->本地缓存中取,取不到->网络缓存中取。
public class ImageUtils {
private MemoryCacheUtil memoryCacheUtil;
private LocalCacheUtil localCacheUtil;
private NetCacheUtil netCacheUtil;
public ImageUtils(){
memoryCacheUtil = new MemoryCacheUtil();
localCacheUtil = new LocalCacheUtil(memoryCacheUtil);
netCacheUtil = new NetCacheUtil(memoryCacheUtil,localCacheUtil);
}
public void display(ImageView imageView, String url, ListView lv_photo_list) {
Bitmap bitmap = null;
/**
* 因内存缓存中取速度较快
* 内存缓存中取,取不到->本地缓存中取,取不到->网络缓存中取
*/
bitmap = memoryCacheUtil.getBitmap(url);//从内存缓存取图片
if(bitmap!=null){
imageView.setImageBitmap(bitmap);
return;
}
bitmap = localCacheUtil.getBitmap(url);//从本地缓存取图片
if(bitmap!=null){
imageView.setImageBitmap(bitmap);
return;
}
// 开启线程访问网络,下载图片,并且展示
netCacheUtil.display(imageView, url,lv_photo_list);
}
}
上述内容就是Android中怎么实现图片三级缓存,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。