- 浏览: 618456 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (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 1315在调试android程序的时候发现设置的断点怎么也进不去 ... -
android利用ZXing进行条码扫描二维码扫描源码简化
2012-01-04 09:59 1949导入项目 @Override public v ... -
Android使用ZXing类库进行条码/二维码识别
2011-12-26 11:24 1818Android使用ZXing类库进行条码/二维码识别(转) ... -
如何在开发时可以让Android应用程序支持安装到SD卡
2011-12-16 08:51 957Android系统在2.1版本之前,应用程序是只能安装到机身内 ... -
用TextView显示带图片的效果及为文本添加链接
2011-12-06 17:13 1810为了实现在TextView中显示图片,有时对图片的宽度与高度有 ... -
android apk 为程序增加代码混淆
2011-11-30 10:09 2645概述 在2.3版本的sdk中可以看到在ANDROID_S ... -
Android 程序的安装、卸载和更新
2011-11-22 11:20 1184安装程序:软件从无到有。 卸载程序:软件从有到无。 ... -
atest201111
2011-11-21 17:04 0eeeee SQLite Developer ... -
android-XXX9.png文件拉伸不失真大家注意了
2011-11-17 14:24 1747什么是9.png: 可能做过任务栏美化 ... -
Android中String资源文件的String.format方法(java)
2011-10-25 16:57 1237很多时候我们感性Google ... -
android 一直在最前面的浮动窗口效果
2011-10-21 15:51 15876今天发现一些软件可以 ... -
Android 对于ListView拖动时变黑问题解决方法
2011-10-21 13:08 1509最近用ListView显示一些String数据 ... -
Android SeekBarPreference浅聊
2011-10-19 15:37 1526由于网上有很多人问到SeekBarPreferenc ... -
在Android中创建启动界面
2011-10-14 09:06 7891、制作一张启动图片splash.png,放置在res ... -
Android 菜单(OptionMenu)大全 建立你自己的菜单
2011-10-13 09:11 694菜单是用户界面中最常见的元素之一,使用非常频繁,在Andro ... -
Android中使用Gson解析JSON数据
2011-10-12 13:33 1558在Android中可以使用Gson解析JSON数据 ... -
android解析json小例子
2011-10-12 12:53 1101今天学习了一下解析json的知识,把我学习的的一个小例子拿出来 ... -
解决android http请求带中文参数会乱码(url编码)
2011-09-29 17:23 3252今天在用android 的 URL url = new U ... -
android 选择本地图片并预览
2011-09-29 14:40 1218adv_sdcard_image_upload.xml ... -
关于 apk文件反编译的方法(dex2jar和JD-GUI)
2011-09-19 11:51 1598觉着这2个工具配合学习android太靠谱了,所以放上来给大家 ...
相关推荐
Android ListView异步加载图片,优化滚动效果,不卡顿、流畅显示。主要给新人了解ListView和AsyncTask、Json等使用。
①ListView异步加载图片的方式 ②给ImageView设置Tag,解决图片覆盖问题 ③采用LruCache缓存已经加载过的图片 ④当ListView滚动时不加载图片,滚动停止时才加载图片,从而达到ListView滑动很流畅的效果 ⑤当...
我们在使用ListView时 用户时长会 连续滚动数屏,且滚动过程中会触发所有的getView的异步任务,getView线程加载图片则会 开很多条线程或者是线程池不够用 堵塞在 前面的getView任务中。直到 逐个执行完成 到达 当前...
解决ListView滑动是卡的问题解决,实现异步加载图片,本地图片缓存,滚动手势识别
最近一段处理跟图片相关的问题,本来是自己写的图片加载,不过有些状态的控制还是比较烦人的,比如ListView滚动时ImageView的重用,所以本着偷懒与充分利用现有资源的态度去网上搜罗图片异步加载的代码,最终在...
2. 将getView中需要加载的图片添加进堆栈,启动异步线程从栈顶开始加载图片,保证当前显示区域的图片被先显示。 3. 调整Load线程优先级为Thread.NORM_PRIORITY-1,不要和UI线程抢时间片,使滚动更流畅。 该代码用...
点击ExpandableListView头部时,子集动态加载。已有子集不重新加载。 ExpandableListView滚动时,头部孤独。 IphoneTreeView功能
主要介绍了Android程序开发ListView+Json+异步网络图片加载+滚动翻页的例子(图片能缓存,图片不错乱) 的相关资料,需要的朋友可以参考下
1.新添加了横向水平滚动条的添加功能实现. horizontalScrollView实现方式. 2.TreeView 基于ListView的实现方式. 3.多级动态异步加载. 其它例子demo优化.
源码smoothie,smoothie是一个开源的组件,提供了简单的API异步加载Android ListView/GridView的项目,以和UI线程分离。Smoothie是手势识别:在Fling手势时,它会必须发起加载项目请求;在滑动列表时,当你的手指按...
[四次元]listview实现图片的异步加载.rar [四次元]listview快速滑动,修改默认的滑动条.rar [四次元]ListView滚动气泡提示.rar [四次元]listview获取网络图片缓存优化.zip [四次元]Location1014.rar [四次元]map_...
为了实现异步的网络图片加载,支持多线程异步加载。 17、Android的开发框架 mobilelite 为Android应用开发提供一个轻量级开发框架,让开发者可以基于HTML/CSS/JAVASCRIPT快速开发android应用界面,同时也能够利用...
简明、完整、全面的安卓开发demo集合,包含如下...48、异步加载图片的二级缓存技术 49、QQ的好友列表展示效果 50、Fragment + ViewPager实现tab滑动切换 51、能够显示在桌面前面的的歌词效果 52、activity切换特效
初学者必看 1、LinearLayout Button、RadioGroup...48、异步加载图片的二级缓存技术 49、QQ的好友列表展示效果 50、Fragment + ViewPager实现tab滑动切换 51、能够显示在桌面前面的的歌词效果 52、activity切换特效
十四、LoaderManager异步加载数据库 14.1 LoaderManager的使用一 14.2 LoaderManager的使用二 十五、多线程编程 15.1 AsyncTask异步任务介绍一 15.2 AsyTask异步任务介绍二 15.3 Handler和Message(一) 15.4 Handler...
ListView 支持延迟加载资源(数据),同步(从内存,从本地数据库...)或异步(HTTP,REST,...)。 动机是,即使您在内存中有可用数据,一旦将其移植到 listView 适配器,使用大量数据(200 多个项目)初始化 ...
影迷 演示项目 概述 ... 将列表滚动到最后一个适配器项可见时会自动调用延迟加载。 一旦 REST API 中没有更多要加载的项目,或者当它达到定义的最大数据长度时,延迟加载将停止。 支持 支持的 API 是
此时此景,笔者只专注Android、Iphone等移动平台开发,看着这些源码心中有万分感慨,写此文章纪念那时那景! Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这...