* 异步加载图片 * 使用方法: * private AsyncImageLoader asyImg = new AsyncImageLoader(); * asyImg.LoadImage(productItems.get(position).getPic(), (ImageView)view.findViewById(R.id.pic)); */public class AsyncImageLoader { // 为了加快速度,在内存中开启缓存(主要应用于重复图片较多时,或者同一个图片要多次被访问,比如在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() + "/maiduo"; /** * * @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.loading); } // 如果缓存过就会从缓存中取出图像,ImageCallback接口中方法也不会被执行 Drawable cacheImage = loadDrawable(url, new AsyncImageLoader.ImageCallback() { // 请参见实现:如果第一次加载url时下面方法会执行 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; }} 详细解决方案
Android异步加载图片并缓存到内存和SD卡下
热度:12 发布时间:2016-05-01 12:25:45.0
相关解决方案
- android 读取byte[]中的元素解决方案
- android 标题栏兑现方式
- android 中Activity向BroadcastReceiver发送数据,该怎么解决
- Android 4.0 为什么模拟器老是提示小弟我谷歌拼音输入法已停止
- android:getSharedPreferences() 这是哪个类的方法解决思路
- android 怎么判断一个程序是否联网
- android RadioButton如何设置默认选中
- android 怎么重新设置锚点
- android 图片对象获取的有关问题
- android 关于服务连接的疑义
- android 怎么实现对view的放大和缩小
- android ID,该如何处理
- 准备复习2-3个月,看java+android,请问有经验者,怎么看效果最好》
- android UI线程与AsyncTask的有关问题
- android(java) 中文乱码的有关问题
- android 动态设立控件高度
- Android test project 编译方法
- android 4.03启动出错,显示"Encryption Unsuccessful"该如何解决
- Android 下面的listView的动态效果怎么实现的?求源代码,多谢
- Android?Palm?Symbian?Windows Mobile?学哪个有“钱图”?解决方案
- Android 开发语言,该怎么解决
- 单个人去做手机开发选什么平台好?android,iphone?解决办法
- Android 虚拟机崩溃的有关问题
- 想学学移动平台的开发 android 还是windows phone7好啊该怎么处理
- Android 上的如何读写设备文件
- Android 2.2 API 汉语文档系列(3) —— AccessibilityService
- 【先睹为快】ArcGIS Android SDK上一版本新特性
- ArcGIS for Android app v2.0.4公布
- android.hardware.USB种介绍
- android linux开发 在线电子书解决方案