`

android端图片缓存实现,特别适用于listview来回滚动

 
阅读更多
转载自:
http://www.open-open.com/lib/view/open1384349254555.html
缓存类就一个:
AsyncBitmapLoader
package com.ikuaishou.kuaishou.utils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.os.Handler;
import android.widget.ImageView;

import com.ikuaishou.kuaishou.R;

public class AsyncBitmapLoader {

// 为了加快速度,在内存中开启缓存(主要应用于重复图片较多时,或者同一个图片要多次被访问,比如在ListView时来回滚动)
public Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
private ExecutorService executorService = Executors.newFixedThreadPool(5); // 固定五个线程来执行任务
private final Handler handler = new Handler();
// SD卡上图片储存地址
private final String path = Environment.getExternalStorageDirectory()
.getPath() + "/ikuaishou";

/**
*
* @param imageUrl
*            图像url地址
* @param callback
*            回调接口
* @return 返回内存中缓存的图像,第一次加载返回null
*/
public Drawable loadDrawable(final String imageUrl,
final ImageCallback callback) {
// 如果缓存过就从缓存中取出数据
if (imageCache.containsKey(imageUrl)) {
SoftReference<Drawable> softReference = imageCache.get(imageUrl);
if (softReference.get() != null) {
return softReference.get();
}
} else if (useTheImage(imageUrl) != null) {
return useTheImage(imageUrl);
}
// 缓存中没有图像,则从网络上取出数据,并将取出的数据缓存到内存中
executorService.submit(new Runnable() {
public void run() {
try {
final Drawable drawable = Drawable.createFromStream(
new URL(imageUrl).openStream(), "image.png");
imageCache.put(imageUrl, new SoftReference<Drawable>(
drawable));
handler.post(new Runnable() {
public void run() {
callback.imageLoaded(drawable);
}
});
saveFile(drawable, imageUrl);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
});
return null;
}

// 从网络上取数据方法
public Drawable loadImageFromUrl(String imageUrl) {
try {

return Drawable.createFromStream(new URL(imageUrl).openStream(),
"image.png");
} catch (Exception e) {
throw new RuntimeException(e);
}
}

// 对外界开放的回调接口
public interface ImageCallback {
// 注意 此方法是用来设置目标对象的图像资源
public void imageLoaded(Drawable imageDrawable);
}

// 引入线程池,并引入内存缓存功能,并对外部调用封装了接口,简化调用过程
public void LoadImage(final String url, final ImageView iv) {
if (iv.getImageMatrix() == null) {
iv.setImageResource(R.drawable.headimgurl);
}
// 如果缓存过就会从缓存中取出图像,ImageCallback接口中方法也不会被执行
Drawable cacheImage = loadDrawable(url,new ImageCallback() {

@Override
public void imageLoaded(Drawable imageDrawable) {
iv.setImageDrawable(imageDrawable);
}
});
if (cacheImage != null) {
iv.setImageDrawable(cacheImage);
}
}

/**
* 保存图片到SD卡上
*
* @param bm
* @param fileName
*
*/
public void saveFile(Drawable dw, String url) {
try {
BitmapDrawable bd = (BitmapDrawable) dw;
Bitmap bm = bd.getBitmap();

// 获得文件名字
final String fileNa = url.substring(url.lastIndexOf("/") + 1,
url.length()).toLowerCase();
File file = new File(path + "/image/" + fileNa);
// 创建图片缓存文件夹
boolean sdCardExist = Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在
if (sdCardExist) {
File maiduo = new File(path);
File ad = new File(path + "/image");
// 如果文件夹不存在
if (!maiduo.exists()) {
// 按照指定的路径创建文件夹
maiduo.mkdir();
// 如果文件夹不存在
} else if (!ad.exists()) {
// 按照指定的路径创建文件夹
ad.mkdir();
}
// 检查图片是否存在
if (!file.exists()) {
file.createNewFile();
}
}

BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(file));
bm.compress(Bitmap.CompressFormat.JPEG, 100, bos);
bos.flush();
bos.close();
} catch (Exception e) {
// TODO: handle exception
}
}

/**
* 使用SD卡上的图片
*
*/
public Drawable useTheImage(String imageUrl) {

Bitmap bmpDefaultPic = null;

// 获得文件路径
String imageSDCardPath = path
+ "/image/"
+ imageUrl.substring(imageUrl.lastIndexOf("/") + 1,
imageUrl.length()).toLowerCase();
File file = new File(imageSDCardPath);
// 检查图片是否存在
if (!file.exists()) {
return null;
}
bmpDefaultPic = BitmapFactory.decodeFile(imageSDCardPath, null);

if (bmpDefaultPic != null || bmpDefaultPic.toString().length() > 3) {
Drawable drawable = new BitmapDrawable(bmpDefaultPic);
return drawable;
} else
return null;
}
}


使用很简单:
asyncBitmapLoader.LoadImage(list.get(position).getPic(), holder.iv_pic);
分享到:
评论

相关推荐

    Android 实现ListView滚动到底部自动加载数据

    总之,实现Android ListView滚动到底部自动加载数据涉及到的主要步骤包括:设置适配器、监听滚动事件、判断是否滚动到底部、加载新数据和更新列表。这个过程需要对Android的基础组件和数据操作有深入的理解,同时也...

    Android 完美的listview自动循环滚动

    "Android 完美的listview自动循环滚动"这个主题聚焦于如何使ListView在到达列表末尾时能够自动循环回滚到顶部,实现类似轮播的效果。这种功能常见于广告轮播、商品推荐等场景,可以提供流畅且连续的用户体验。 首先...

    监听listview垂直滚动距离

    "监听listview垂直滚动距离"是Android开发中的一个常见需求,它可以帮助开发者实现诸如无限滚动加载、顶部悬浮按钮(如“返回顶部”)等功能。下面将详细解释如何实现这个功能。 首先,我们需要了解ListView的基本...

    Android ListView滚动到底部自动加载数据

    `Android ListView滚动到底部自动加载数据`是一个常见的功能需求,特别是在实现无限滚动或者分页加载的场景下,比如社交媒体应用、电商应用的商品列表等。当用户滚动到ListView的底部时,系统自动触发加载更多数据的...

    c# listview 实现循环滚动显示

    当你需要实现一个类似新闻滚动条或者广告轮播的效果时,`ListView`的循环滚动显示功能就显得尤为重要。本篇文章将深入探讨如何在C#中实现ListView的循环滚动效果。 首先,我们要理解`ListView`的基本用法。`...

    两个ListView同步滚动

    在Android开发中,ListView是常用的数据展示控件,它能够高效地处理大量数据并实现滚动。当我们在一个界面中需要展示两个或多个ListView,并希望它们能保持同步滚动时,这通常是为了提供更好的用户体验,比如对比...

    ListView块状滚动条加分批加载数据

    本项目实现了ListView的两个关键特性:块状滚动条(类似微博、QQ微博)和分批加载数据(即无限滚动或下拉加载更多)。下面将详细讲解这两个功能的实现原理及步骤。 **一、ListView自定义滚动条** 1. **创建自定义...

    listview优化图片缓存例子

    "LazyList" 是一个适用于ListView的开源库,它提供了一种高效且自动化的图片缓存解决方案。主要特点包括: - 自动缓存:当图片被加载到ListView的ImageView时,LazyList会自动将其存入内存和磁盘缓存。 - 异步加载...

    Android支持横行滚动的ListView控件

    总的来说,"Android支持横行滚动的ListView控件"是一个提高用户体验的创新设计,它使得用户可以在水平方向上浏览长列表,特别适用于展示水平方向有连续性的数据,如时间轴、图片轮播等场景。通过结合...

    android listView图片异步加载(拖动时不加载,双缓存)

    通过以上步骤,我们可以实现一个高效的图片异步加载方案,确保ListView在滚动时保持流畅,同时充分利用双缓存策略降低网络请求频率,提升应用性能。在实际项目中,可以根据需求选择合适的第三方库,或者自定义实现以...

    listView快速滑动图片缓存实例

    综上所述,"listView快速滑动图片缓存实例"涉及的关键技术包括:Bitmap缓存管理、内存和磁盘缓存策略、图片加载优化以及ListView的滚动监听和Adapter的重用。通过这些手段,可以在保证ListView流畅滑动的同时,提供...

    android listview 自动往上滚动

    综上所述,实现"android listview 自动往上滚动"的效果,需要掌握Android的ListView滚动机制、动画系统、监听事件以及性能优化等多方面的知识。通过对这些知识点的深入理解和实践,开发者可以创造出更加生动有趣的...

    android的listview嵌套listview,列表嵌套列表 android studio版本

    总结来说,实现Android的ListView嵌套ListView需要理解ListView的工作机制,创建并管理两个Adapter,以及在布局文件中正确地嵌套ListView。这虽然不是特别高深的技术,但却是Android开发中常见的需求,熟练掌握能...

    listview自动滚动

    在Android应用开发中,我们经常需要实现ListView的自动滚动功能,这通常用于模拟滚动效果、展示通知或者实现自动轮播等效果。在本篇内容中,我们将深入探讨如何在Android中实现ListView的自动滚动。 首先,自动滚动...

    android 适用于listview中girdview

    而标题提到的“android适用于listview中girdview”,实际上是在描述一种在ListView中嵌套GridView的场景,以实现更复杂的列表布局。 ListView是一种可以滚动的视图容器,它可以根据数据集动态地创建视图,这样就...

    Android-滑动listview标题置顶listview吸顶效果

    在Android应用开发中,UI设计和用户体验是至关重要的部分,特别是在构建列表视图(ListView)时。本知识点主要探讨如何实现“滑动ListView时标题置顶”和“ListView吸顶效果”,以及如何使安卓系统状态栏透明化。这些...

    Android应用源码之ListView停止滚动开启下载图片.zip

    这个“Android应用源码之ListView停止滚动开启下载图片”源码示例主要关注如何优化ListView的性能,特别是当列表项包含网络图片时。这里我们将深入探讨几个关键知识点: 1. **ListView与Adapter**: ListView的...

    安卓listview相关相关-listview获取网络图片缓存优化.zip

    总的来说,这份资料包提供了关于ListView图片加载优化的一个实例,帮助开发者理解和实现懒加载和缓存策略,提升应用性能。通过深入学习和实践,你可以更好地掌握Android应用中的图片加载优化技巧。

    Android ListView 无限循环滚动源码

    下面我们将深入探讨如何通过源码实现Android ListView的无限循环滚动功能。 首先,我们需要创建一个自定义的Adapter,这个Adapter需要管理两个数据集,一个为主数据集,另一个为辅助数据集。主数据集包含实际的数据...

Global site tag (gtag.js) - Google Analytics