- 浏览: 634784 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (314)
- 生活 (2)
- c# (37)
- 技术 (3)
- 400电话 (0)
- 400常见问题 (0)
- 400资费 (0)
- html (7)
- css (0)
- 数据库 (7)
- javascript (16)
- php (33)
- asp.net mvc2 (10)
- mysql (9)
- C# 3.0 LinQ (10)
- vs2005或vs2008 (4)
- flash and as3 (7)
- fms (1)
- dedeCMS (11)
- java (33)
- j2me (1)
- swing (1)
- c++ (1)
- jquery easyui (3)
- jquery (5)
- android (29)
- MongoDB (9)
- VtigerCRM (1)
- test (0)
- linux (30)
- nutch (2)
- SqlServer数据库 (2)
- 数据检索 (2)
- java抓取 (11)
- 乐天 (1)
- 淘宝 (1)
- Silverlight4.0 (6)
- sphinx实时索引 (5)
- ecshop (9)
- codeigniter(CI) (3)
- axure6 (1)
- 京东店铺装修教程 (2)
- xpath (1)
- joomla (2)
- bpm (1)
- Bootstrap (2)
- knockout (4)
- ecstore (4)
- css3 (1)
- 微信 (2)
- dede (0)
- soa_edi (1)
- odoo (0)
- web (1)
最新评论
-
骑着蜗牛超F1:
在ie6下报了个stack overflow at line ...
兼容ie6和ie7 的16进制码流在html中显示为图片代码(base64) -
冰之海洋:
好像少了一句代码吧? FloatingFunc.show(th ...
android 一直在最前面的浮动窗口效果 -
yanzhoupuzhang:
连接有问题!
iis7.0官方下载 IIS 7.0(微软Web服务器组件IIS 7.0) 官方(windows 2003,XP,2000) -
whatable:
唉,楼主你都没有搞清楚重量级和轻量级。。。。既然引用了SWT, ...
java swing 内置浏览器打开网页显示flash图表-swt Browser应用 -
yy_owen:
我晕啊,你链接的什么内容额,我要的iis,你链接个视频什么意思 ...
iis7.0官方下载 IIS 7.0(微软Web服务器组件IIS 7.0) 官方(windows 2003,XP,2000)
LoadImage.java
package com.gowin.cach; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import android.graphics.Bitmap; import android.os.Handler; import android.os.Message; import android.widget.ImageView; public class LoadImage { private ExecutorService executorService; // 固定五个线程来 private ImageMemoryCache memoryCache;// 内存缓存 private ImageFileCache fileCache;// 文件缓存 private Map<String, ImageView> taskMap;// 存放任务 public LoadImage() { executorService = Executors.newFixedThreadPool(10); memoryCache = new ImageMemoryCache(); fileCache = new ImageFileCache(); taskMap = new HashMap<String, ImageView>(); } public void addTask(String url, ImageView img) { Bitmap bitmap=memoryCache.getBitmapFromCache(url); if(bitmap!=null) { img.setImageBitmap(bitmap); }else { synchronized (taskMap) { taskMap.put(Integer.toString(img.hashCode()), img); } } } public void doTask() { synchronized (taskMap) { Collection<ImageView> con = taskMap.values(); for (ImageView i : con) { if (i != null) { if (i.getTag() != null) { loadImage((String) i.getTag(), i); } } } taskMap.clear(); } } private void loadImage(String url, ImageView img) { /*** 加入新的任务 ***/ executorService.submit(new TaskWithResult(new TaskHandler(url, img), url)); } /*** 获得一个图片,从三个地方获取,首先是内存缓存,然后是文件缓存,最后从网络获取 ***/ private Bitmap getBitmap(String url) { // 从内存缓存中获取图片 Bitmap result; result = memoryCache.getBitmapFromCache(url); if (result == null) { // 文件缓存中获取 result = fileCache.getImage(url); if (result == null) { // 从网络获取 result = ImageGetForHttp.downloadBitmap(url); if (result != null) { memoryCache.addBitmapToCache(url, result); fileCache.saveBmpToSd(result, url); } } else { // 添加到内存缓存 memoryCache.addBitmapToCache(url, result); } } return result; } /*** 完成消息 ***/ private class TaskHandler extends Handler { String url; ImageView img; public TaskHandler(String url, ImageView img) { this.url = url; this.img = img; } @Override public void handleMessage(Message msg) { /*** 查看imageview需要显示的图片是否被改变 ***/ if (img.getTag().equals(url)) { if (msg.obj != null) { Bitmap bitmap = (Bitmap) msg.obj; img.setImageBitmap(bitmap); } } } } /*** 子线程任务 ***/ private class TaskWithResult implements Callable<String> { private String url; private Handler handler; public TaskWithResult(Handler handler, String url) { this.url = url; this.handler = handler; } @Override public String call() throws Exception { Message msg = new Message(); msg.obj = getBitmap(url); if (msg.obj != null) { handler.sendMessage(msg); } return url; } } }
ImageMemoryCache.java
(http://www.my400800.cn
)
package com.gowin.cach; import java.lang.ref.SoftReference; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.concurrent.ConcurrentHashMap; import android.graphics.Bitmap; /**** *内存中的缓存 ****/ public class ImageMemoryCache { private static final int HARD_CACHE_CAPACITY = 30; private HashMap<String, Bitmap> mHardBitmapCache ; private final static ConcurrentHashMap<String, SoftReference<Bitmap>> mSoftBitmapCache = new ConcurrentHashMap<String, SoftReference<Bitmap>>(HARD_CACHE_CAPACITY / 2); public ImageMemoryCache() { mHardBitmapCache = new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY / 2, 0.75f, true) { /** * */ private static final long serialVersionUID = 1L; @Override protected boolean removeEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) { if (size() > HARD_CACHE_CAPACITY) { // Entries push-out of hard reference cache are transferred to soft reference cache mSoftBitmapCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue())); return true; } else return false; } }; } /** * 从缓存中获取图片 */ public Bitmap getBitmapFromCache(String url) { // 先从mHardBitmapCache缓存中获取 synchronized (mHardBitmapCache) { final Bitmap bitmap =mHardBitmapCache.get(url); if (bitmap != null) { //如果找到的话,把元素移到linkedhashmap的最前面,从而保证在LRU算法中是最后被删除 mHardBitmapCache.remove(url); mHardBitmapCache.put(url,bitmap); return bitmap; } } //如果mHardBitmapCache中找不到,到mSoftBitmapCache中找 SoftReference<Bitmap>bitmapReference = mSoftBitmapCache.get(url); if (bitmapReference != null) { final Bitmap bitmap =bitmapReference.get(); if (bitmap != null) { //将图片移回硬缓存 mHardBitmapCache.put(url, bitmap); mSoftBitmapCache.remove(url); return bitmap; } else { mSoftBitmapCache.remove(url); } } return null; } /***添加图片到缓存***/ public void addBitmapToCache(String url, Bitmap bitmap) { if (bitmap != null) { synchronized (mHardBitmapCache) { mHardBitmapCache.put(url, bitmap); } } } }
ImageFileCache.java
package com.gowin.cach; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; import java.util.Comparator; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Environment; import android.os.StatFs; import android.util.Log; public class ImageFileCache { private static final String CACHDIR = "data/gowin/imgCach"; private static final String WHOLESALE_CONV = ".cach"; /**过期时间3天**/ private static final long mTimeDiff = 3 * 24 * 60 * 60 * 1000; public ImageFileCache() { //清理文件缓存 removeCache(getDirectory()); } public Bitmap getImage(final String url) { final String path = getDirectory() + "/" + convertUrlToFileName(url); File file = new File(path); if (file.exists()) { Bitmap bmp=BitmapFactory.decodeFile(path); if(bmp==null) { file.delete(); }else { updateFileTime(path); return bmp; } } return null; } /***缓存空间大小****/ private static final int FREE_SD_SPACE_NEEDED_TO_CACHE=10; public void saveBmpToSd(Bitmap bm, String url) { if (bm == null) { //需要保存的是一个空值 return; } //判断sdcard上的空间 if (FREE_SD_SPACE_NEEDED_TO_CACHE >freeSpaceOnSd()) { //SD空间不足 return; } String filename =convertUrlToFileName(url); String dir = getDirectory(); File file = new File(dir +"/" + filename); try { file.createNewFile(); OutputStream outStream = new FileOutputStream(file); bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream); outStream.flush(); outStream.close(); } catch (FileNotFoundException e) { Log.w("ImageFileCache","FileNotFoundException"); } catch (IOException e) { Log.w("ImageFileCache","IOException"); } } private static final int CACHE_SIZE=10; // 清理缓存 /** * 计算存储目录下的文件大小, * 当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定 * 那么删除40%最近没有被使用的文件 * * @param dirPath * @param filename */ private boolean removeCache(String dirPath) { File dir = new File(dirPath); File[] files = dir.listFiles(); if (files == null) { return true; } if (!android.os.Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED)) { return false; } int dirSize = 0; for (int i = 0; i < files.length; i++) { if (files[i].getName().contains(WHOLESALE_CONV)) { dirSize += files[i].length(); } } if (dirSize > CACHE_SIZE * MB || FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) { int removeFactor = (int) ((0.4 * files.length) + 1); Arrays.sort(files, new FileLastModifSort()); Log.i("ImageFileCache", "清理缓存文件"); for (int i = 0; i < removeFactor; i++) { if (files[i].getName().contains(WHOLESALE_CONV)) { files[i].delete(); } } } if (freeSpaceOnSd() <= CACHE_SIZE) { return false; } return true; } /** * TODO 根据文件的最后修改时间进行排序 * */ private class FileLastModifSort implements Comparator<File> { public int compare(File arg0, File arg1) { if (arg0.lastModified() > arg1.lastModified()) { return 1; } else if (arg0.lastModified() == arg1.lastModified()) { return 0; } else { return -1; } } } /** * 删除过期文件 * * @param dirPath * @param filename */ public void removeExpiredCache(String dirPath, String filename) { File file = new File(dirPath, filename); if (System.currentTimeMillis() - file.lastModified() > mTimeDiff) { Log.i("ImageFileCache", "Clear some expiredcache files "); file.delete(); } } /** * 修改文件的最后修改时间 * 这里需要考虑,是否将使用的图片日期改为当前日期 * @param path */ public void updateFileTime(String path) { File file = new File(path); long newModifiedTime = System.currentTimeMillis(); file.setLastModified(newModifiedTime); } /** * 计算sdcard上的剩余空间 * @return */ private int MB=1024*1024; private int freeSpaceOnSd() { StatFs stat = new StatFs(Environment.getExternalStorageDirectory() .getPath()); double sdFreeMB = ((double)stat.getAvailableBlocks() * (double) stat.getBlockSize()) / MB; return (int) sdFreeMB; } /**将url转成文件名**/ private String convertUrlToFileName(String url) { String[] strs = url.split("/"); return strs[strs.length - 1] + WHOLESALE_CONV; } /**获得缓存目录**/ private String getDirectory() { String dir = getSDPath() + "/" + CACHDIR; String substr = dir.substring(0, 4); if (substr.equals("/mnt")) { dir = dir.replace("/mnt", ""); } return dir; } /**** 取SD卡路径不带/ ****/ public String getSDPath() { File sdDir = null; boolean sdCardExist = Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED); // 判断sd卡是否存在 if (sdCardExist) { sdDir = Environment.getExternalStorageDirectory();// 获取跟目录 } if(sdDir!=null) { return sdDir.toString(); }else { return ""; } } }
ImageGetForHttp.java
package com.gowin.cach; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.http.AndroidHttpClient; import android.util.Log; public class ImageGetForHttp { private static final String LOG_TAG="ImageGetForHttp"; public static Bitmap downloadBitmap(String url) { //final int IO_BUFFER_SIZE = 4 * 1024; // AndroidHttpClient is not allowed to be used from the main thread final HttpClient client = AndroidHttpClient.newInstance("Android"); final HttpGet getRequest = new HttpGet(url); try { HttpResponse response = client.execute(getRequest); final int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { Log.w("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url); return null; } final HttpEntity entity = response.getEntity(); if (entity != null) { InputStream inputStream = null; try { inputStream = entity.getContent(); // return BitmapFactory.decodeStream(inputStream); // Bug on slow connections, fixed in future release. FilterInputStream fit= new FlushedInputStream(inputStream); return BitmapFactory.decodeStream(fit); } finally { if (inputStream != null) { inputStream.close(); } entity.consumeContent(); } } } catch (IOException e) { getRequest.abort(); Log.w(LOG_TAG, "I/O error while retrieving bitmap from " + url, e); } catch (IllegalStateException e) { getRequest.abort(); Log.w(LOG_TAG, "Incorrect URL: " + url); } catch (Exception e) { getRequest.abort(); Log.w(LOG_TAG, "Error while retrieving bitmap from " + url, e); } finally { if ((client instanceof AndroidHttpClient)) { ((AndroidHttpClient) client).close(); } } return null; } /* * An InputStream that skips the exact number of bytes provided, unless it reaches EOF. */ static class FlushedInputStream extends FilterInputStream { public FlushedInputStream(InputStream inputStream) { super(inputStream); } @Override public long skip(long n) throws IOException { long totalBytesSkipped = 0L; while (totalBytesSkipped < n) { long bytesSkipped = in.skip(n - totalBytesSkipped); if (bytesSkipped == 0L) { int b = read(); if (b < 0) { break; // we reached EOF } else { bytesSkipped = 1; // we read one byte } } totalBytesSkipped += bytesSkipped; } return totalBytesSkipped; } } }
使用时,要救imageview的tag是需要下载的url
在getview时先addtask
当滚动停止的时候调用doTask
评论
3 楼
wuhanliupeng
2012-02-19
能把一个完整一点的demo 给我一份吗? 我学生 931861057@qq.com 谢谢
2 楼
wuhanliupeng
2012-02-19
不知道怎么调用的呢
1 楼
xinyao
2011-12-21
你好,很强大!
我把你的代码copy上去,调用成功了,但是有个问题,就是第一次listview的滚动停止不调用,就是一开始不显示图片,是怎么解决的?
我把你的代码copy上去,调用成功了,但是有个问题,就是第一次listview的滚动停止不调用,就是一开始不显示图片,是怎么解决的?
发表评论
-
andorid eclipse断点调试失灵
2013-05-09 15:06 1379在调试android程序的时候发现设置的断点怎么也进不去 ... -
android利用ZXing进行条码扫描二维码扫描源码简化
2012-01-04 09:59 2009导入项目 @Override public v ... -
Android使用ZXing类库进行条码/二维码识别
2011-12-26 11:24 1874Android使用ZXing类库进行条码/二维码识别(转) ... -
如何在开发时可以让Android应用程序支持安装到SD卡
2011-12-16 08:51 1008Android系统在2.1版本之前,应用程序是只能安装到机身内 ... -
用TextView显示带图片的效果及为文本添加链接
2011-12-06 17:13 1860为了实现在TextView中显示图片,有时对图片的宽度与高度有 ... -
android apk 为程序增加代码混淆
2011-11-30 10:09 2723概述 在2.3版本的sdk中可以看到在ANDROID_S ... -
Android 程序的安装、卸载和更新
2011-11-22 11:20 1247安装程序:软件从无到有。 卸载程序:软件从有到无。 ... -
atest201111
2011-11-21 17:04 0eeeee SQLite Developer ... -
android-XXX9.png文件拉伸不失真大家注意了
2011-11-17 14:24 1806什么是9.png: 可能做过任务栏美化 ... -
Android中String资源文件的String.format方法(java)
2011-10-25 16:57 1297很多时候我们感性Google ... -
android 一直在最前面的浮动窗口效果
2011-10-21 15:51 15976今天发现一些软件可以 ... -
Android 对于ListView拖动时变黑问题解决方法
2011-10-21 13:08 1588最近用ListView显示一些String数据 ... -
Android SeekBarPreference浅聊
2011-10-19 15:37 1591由于网上有很多人问到SeekBarPreferenc ... -
在Android中创建启动界面
2011-10-14 09:06 8291、制作一张启动图片splash.png,放置在res ... -
Android 菜单(OptionMenu)大全 建立你自己的菜单
2011-10-13 09:11 741菜单是用户界面中最常见的元素之一,使用非常频繁,在Andro ... -
Android中使用Gson解析JSON数据
2011-10-12 13:33 1613在Android中可以使用Gson解析JSON数据 ... -
android解析json小例子
2011-10-12 12:53 1170今天学习了一下解析json的知识,把我学习的的一个小例子拿出来 ... -
解决android http请求带中文参数会乱码(url编码)
2011-09-29 17:23 3287今天在用android 的 URL url = new U ... -
android 选择本地图片并预览
2011-09-29 14:40 1282adv_sdcard_image_upload.xml ... -
关于 apk文件反编译的方法(dex2jar和JD-GUI)
2011-09-19 11:51 1650觉着这2个工具配合学习android太靠谱了,所以放上来给大家 ...
相关推荐
因此,我们需要采用异步加载图片的方式,同时为了优化性能,通常会采用双缓存策略。本文将详细介绍如何在ListView中实现图片的异步加载,并且在用户拖动时不加载,以提高滚动流畅性。 一、异步加载原理 异步加载是...
这里的“android listView 异步加载图片”指的是在不阻塞UI线程的情况下,从网络、本地存储或其他来源加载图片到ListView中的技术。 这篇名为“ImageLoader”的Java文件很可能就是一个实现图片异步加载的工具类。在...
为了解决这个问题,开发者通常会采用“异步加载”策略,特别是在加载图片和数据时。本文将深入探讨ListView滚动实现异步加载这一技术,以及如何通过优化来提高用户体验。 1. **异步加载原理** 异步加载的基本思想...
在Android开发中,...通过以上介绍,你应该对Android ListView的优化有了更深入的理解,特别是异步加载图片和Json解析这两个关键环节。实践中,结合各种优化策略,能有效提升ListView的性能,提供流畅的用户体验。
3. **异步加载更多数据**:当判断到ListView滚动到底部后,我们需要执行异步加载数据的操作。这通常涉及到网络请求或数据库查询。可以使用AsyncTask、Handler、Retrofit、Volley等工具来处理网络请求。加载数据的...
本篇文章将深入探讨如何在Android中实现ListView异步加载图片,主要涉及以下几个关键知识点: 1. **AsyncTask**:Android提供了AsyncTask类,用于在后台线程执行耗时操作,并在UI线程更新结果。在图片加载场景中,...
"Android中ListView全面完美的网络图片异步加载"这一主题正是解决这些问题的关键。 首先,我们需要理解异步加载的概念。异步加载意味着在后台线程处理耗时操作,如下载和解码图片,而不是在主线程中执行,这样可以...
为了解决这个问题,我们需要实现ListView的异步加载图片功能。本篇文章将详细介绍如何通过软引用缓存图片,实现高效、流畅的异步加载机制。 一、异步加载原理 异步加载的基本思想是将耗时的操作(如网络请求和图片...
本实例将详细讲解如何实现“Android ListView异步加载图片”,结合线程池、数据库和本地保存来优化性能。 首先,我们需要理解异步加载的概念。在Android中,由于主线程负责用户界面的更新,因此不应在主线程中执行...
"android listview 异步加载图片并防止错位"这个主题就是针对这些问题提出的一种解决方案。 异步加载图片是为了避免在主线程中执行耗时操作,导致UI卡顿。通常,我们使用异步任务(如AsyncTask)或者专门的图片加载...
然而,在实际开发中,当我们需要在RecyclerView中异步加载图片时,可能会遇到图片显示乱序的问题。本文将深入探讨这个问题及其解决方案。 首先,我们来理解为什么会出现图片乱序的现象。这是因为RecyclerView在滚动...
通过以上方法,我们可以有效地解决Android ListView中异步加载图片时出现的图片错位问题,提供流畅且高效的用户体验。在实际开发中,应根据项目的具体需求,灵活运用各种策略,实现最佳的图片加载效果。
然而,当这个列表包含网络图片时,如果不进行优化,可能会导致性能问题,如滚动卡顿、内存泄漏等。"异步加载网络图片"就是解决这些问题的关键技术。本文将深入探讨如何在ListView中实现异步加载网络图片,提升应用的...
因此,为了提升用户体验,我们需要采用异步加载图片的技术。这个"Android listview实现图片的异步加载Demo.zip"就是一个示例,它展示了如何在ListView中高效地加载网络或本地的图片。 首先,我们需要理解异步加载的...
然而,当ListView中的每个item都需要加载图片时,如果不采取异步加载策略,可能会导致应用性能下降,用户体验受到影响,因为主线程会因处理大量图片加载而变得卡顿。本教程将深入讲解如何在ListView中实现异步加载...
综上所述,"androidListView图片异步加载"涉及的知识点包括Android的异步编程模型(如AsyncTask)、图片缓存策略、ListView的优化以及图片加载库的使用。通过实践这个项目,初学者不仅可以掌握异步加载的原理,还能...
总结,优化ListView和实现异步加载是提升Android应用性能的关键。通过上述策略,我们可以显著改善ListView的滚动性能,减少内存消耗,同时提供更流畅的用户体验。正确理解和应用这些技术,将使你的Android应用更具...
本篇将深入探讨如何对ListView进行优化,以及如何实现图片的异步加载和缓存策略,以避免这些问题。 **1. ListView优化** ListView的优化主要涉及以下几个方面: 1.1 **convertView复用机制**:ListView的Adapter...