- 浏览: 65885 次
- 性别:
- 来自: 湖北人在北京
最近访客 更多访客>>
文章分类
最新评论
-
手机测试:
我在使用tcpdump 这条命令时提示我找不到合适的设备,但是 ...
android下抓包 -
lfh001001:
可是运行时报错,还需要加入其他什么代码么?
启动动画 -
hibernater:
转化成小图,大图recycle掉也可以
异步加载图片 -
zuo_huai:
我也发现了内存溢出的情况,请要怎么去处理呀!
异步加载图片 -
aa87963014:
圈子加了是加了。但是好像不是很活跃。
坛子?圈子? 还是 q ...
异步加载图片
前几天记得说要分享一下异步下载加载图片的经验,最近一直在研究Cocos2d,把这事耽误了。今天就写了写
如果不怕图片那个内存溢出的bug的话。可以使用ListView,GridView等等,如果担心这个问题,可以使用ImageView
既然是异步加载,那就采用多线程下载吧。 这个例子里面也就用了一个线程池
1.
//初始化线程池
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 3,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>());
2.
//构建一个ListView
listView = (ListView) findViewById(R.id.listview);
3.
//启动一个下载列表的线程
threadPool.execute(new LoadImagesListThread());
4.
/** * 下载图片列表的线程 * @author zhu * */ class LoadImagesListThread extends Thread{ @Override public void run() { //TODO 获取下载图片列表的 datas = HttpUtils.LoadImagesList(); if(datas != null && datas.size()>0){ //通知显示列表 handler.sendEmptyMessage(SHOW_IMAGES); //循环启动线程下载图片 for (int i = 0; i < datas.size(); i++) { threadPool.execute(new LoadImageThread()); } }else{ //TODO 通知没有数据 handler.sendEmptyMessage(NO_IMAGES); } } }
5.
下载图片的线程如下,很简单
class LoadImageThread extends Thread{ int position; public LoadImageThread(int position){ this.position = position; } @Override public void run() { //TODO 下载图片。这个下载方法里面可以先判断是否本地缓存有,如果有,就读缓存。没有就下载,再写缓存 datas.get(position).bitmap = HttpUtils.loadImage(datas.get(position).url); handler.sendEmptyMessage(SHOW_IMAGE); } }
6.
handler里面主要做些刷新的工作
Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { switch (msg.what) { case SHOW_IMAGES: adapter = new MyAdapter(); listView.setAdapter(adapter); break; case NO_IMAGES: Toast.makeText(MainActivity.this, "no images", Toast.LENGTH_LONG).show(); break; case SHOW_IMAGE: adapter.notifyDataSetChanged(); break; default: break; } }; };
至此一个简单的异步加载图片的功能完成了。
图片太多。使用ListView,GridView的时候会报内存溢出的错误,我的经验是320x480大小的12张左右必报。坛子里也讨论了许久,没有结果,都是缩放图片或者避开这个大量图片的问题。我就采用的是避开大量图片的方法。过几天再写出来
评论
10 楼
hibernater
2010-09-02
转化成小图,大图recycle掉也可以
9 楼
zuo_huai
2010-08-29
我也发现了内存溢出的情况,请要怎么去处理呀!
8 楼
aa87963014
2010-08-25
圈子加了是加了。但是好像不是很活跃。
坛子?圈子? 还是 q q 群?
坛子?圈子? 还是 q q 群?
7 楼
luodaijun
2010-08-24
IO操作工具类,其实是包装了apache commons-io
package com.zbkc.mamclient.util;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Created by IntelliJ IDEA.
* User: 罗代均
* Date: 2010-8-23
* Time: 0:17:32
*/
public class IOUtilsEx extends IOUtils {
/**
* 拷贝URL内容到输出流
*
* @param srcUrl
*/
public static void copyUrl(String srcUrl, OutputStream destOutpstream) {
InputStream is = null;
HttpEntity entity = null;
HttpClient client = null;
try {
client = new DefaultHttpClient();
HttpGet get = new HttpGet(srcUrl);
HttpResponse response = client.execute(get);
entity = response.getEntity();
is = entity.getContent();
copy(is, destOutpstream);
} catch (IOException ex) {
} finally {
if (entity != null) {
try {
entity.consumeContent();
} catch (IOException e) {
}
}
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(destOutpstream);
}
}
}
package com.zbkc.mamclient.util;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Created by IntelliJ IDEA.
* User: 罗代均
* Date: 2010-8-23
* Time: 0:17:32
*/
public class IOUtilsEx extends IOUtils {
/**
* 拷贝URL内容到输出流
*
* @param srcUrl
*/
public static void copyUrl(String srcUrl, OutputStream destOutpstream) {
InputStream is = null;
HttpEntity entity = null;
HttpClient client = null;
try {
client = new DefaultHttpClient();
HttpGet get = new HttpGet(srcUrl);
HttpResponse response = client.execute(get);
entity = response.getEntity();
is = entity.getContent();
copy(is, destOutpstream);
} catch (IOException ex) {
} finally {
if (entity != null) {
try {
entity.consumeContent();
} catch (IOException e) {
}
}
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(destOutpstream);
}
}
}
6 楼
luodaijun
2010-08-24
aa87963014 写道
ls 和我的做法一样 保存到本地。
File dir = cacheFile.getParentFile();
if (!dir.exists()) {
dir.mkdirs();
}
这个判断 我那到其他地方去了,就不用每次都判断一次。
ThreadPoolFactory 线程池? 我对这个不太熟悉 有什么特别的好处吗?
你是怎么实现的?
还有 我的 imageView 在listView里面 下载完之后 还要更新视图 感觉有点怪怪的。
不知道 有没什么好的方法
File dir = cacheFile.getParentFile();
if (!dir.exists()) {
dir.mkdirs();
}
这个判断 我那到其他地方去了,就不用每次都判断一次。
ThreadPoolFactory 线程池? 我对这个不太熟悉 有什么特别的好处吗?
你是怎么实现的?
还有 我的 imageView 在listView里面 下载完之后 还要更新视图 感觉有点怪怪的。
不知道 有没什么好的方法
这个判断性能影响有限,主要是为了这个控件更加健壮,线程池用Java自带的
package com.zbkc.mamclient.util;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by IntelliJ IDEA.
* User: 罗代均
* Date: 2010-8-5
* Time: 21:14:02
* 线程池
*/
public class ThreadPoolFactory {
private static ThreadPoolFactory ourInstance = new ThreadPoolFactory();
public static ThreadPoolFactory getInstance() {
return ourInstance;
}
private ExecutorService threadPool;
private ThreadPoolFactory() {
threadPool = Executors.newCachedThreadPool();
}
/**
* 提交给线程池执行
*
* @param run
*/
public void execute(Runnable run) {
threadPool.submit(run);
}
}
5 楼
zhuixinjian
2010-08-24
学android居然没有加入组织。落后了啊
搜索下hong老大的坛子。
搜索下hong老大的坛子。
4 楼
aa87963014
2010-08-24
ls 和我的做法一样 保存到本地。
File dir = cacheFile.getParentFile();
if (!dir.exists()) {
dir.mkdirs();
}
这个判断 我那到其他地方去了,就不用每次都判断一次。
ThreadPoolFactory 线程池? 我对这个不太熟悉 有什么特别的好处吗?
你是怎么实现的?
还有 我的 imageView 在listView里面 下载完之后 还要更新视图 感觉有点怪怪的。
不知道 有没什么好的方法
File dir = cacheFile.getParentFile();
if (!dir.exists()) {
dir.mkdirs();
}
这个判断 我那到其他地方去了,就不用每次都判断一次。
ThreadPoolFactory 线程池? 我对这个不太熟悉 有什么特别的好处吗?
你是怎么实现的?
还有 我的 imageView 在listView里面 下载完之后 还要更新视图 感觉有点怪怪的。
不知道 有没什么好的方法
3 楼
luodaijun
2010-08-24
package com.zbkc.mamclient.ui.common;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
import com.zbkc.mamclient.util.IOUtilsEx;
import com.zbkc.mamclient.util.ThreadPoolFactory;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
/**
* Created by IntelliJ IDEA.
* User: 罗代均
* Date: 2010-8-23
* Time: 1:05:37
*/
public class WebImageView extends ImageView {
private final static String TAG = WebImageView.class.getName();
private Handler handler = new Handler();
public WebImageView(Context context) {
super(context);
}
public WebImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public WebImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* @param url 图片的URL地址
* @param cacheFile 图片第一次下载后,存到本地文件,下次不用网络下载
*/
public void setImageUrl(final String url, final File cacheFile) {
Log.d(TAG, "load image,url:" + url + ",cacheFile:" + cacheFile.getAbsolutePath());
File dir = cacheFile.getParentFile();
if (!dir.exists()) {
dir.mkdirs();
}
if (cacheFile.exists()) {
setImageBitmap(BitmapFactory.decodeFile(cacheFile.getAbsolutePath()));
return;
}
ThreadPoolFactory.getInstance().execute(new Runnable() {
public void run() {
try {
IOUtilsEx.copyUrl(url, new FileOutputStream(cacheFile));
handler.post(new Runnable() {
public void run() {
setImageBitmap(BitmapFactory.decodeFile(cacheFile.getAbsolutePath()));
}
});
} catch (Exception e) {
Log.e(TAG, "setImageUrl error", e);
}
}
});
}
public void setImageUrl(final String url) {
Log.d(TAG, "load image,url:" + url);
ThreadPoolFactory.getInstance().execute(new Runnable() {
public void run() {
InputStream is = null;
try {
is = new URL(url).openStream();
final Bitmap bmp = BitmapFactory.decodeStream(is);
handler.post(new Runnable() {
public void run() {
setImageBitmap(bmp);
}
});
} catch (Exception e) {
Log.e(TAG, "setImageUrl error", e);
} finally {
IOUtils.closeQuietly(is);
}
}
});
}
}
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
import com.zbkc.mamclient.util.IOUtilsEx;
import com.zbkc.mamclient.util.ThreadPoolFactory;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
/**
* Created by IntelliJ IDEA.
* User: 罗代均
* Date: 2010-8-23
* Time: 1:05:37
*/
public class WebImageView extends ImageView {
private final static String TAG = WebImageView.class.getName();
private Handler handler = new Handler();
public WebImageView(Context context) {
super(context);
}
public WebImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public WebImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* @param url 图片的URL地址
* @param cacheFile 图片第一次下载后,存到本地文件,下次不用网络下载
*/
public void setImageUrl(final String url, final File cacheFile) {
Log.d(TAG, "load image,url:" + url + ",cacheFile:" + cacheFile.getAbsolutePath());
File dir = cacheFile.getParentFile();
if (!dir.exists()) {
dir.mkdirs();
}
if (cacheFile.exists()) {
setImageBitmap(BitmapFactory.decodeFile(cacheFile.getAbsolutePath()));
return;
}
ThreadPoolFactory.getInstance().execute(new Runnable() {
public void run() {
try {
IOUtilsEx.copyUrl(url, new FileOutputStream(cacheFile));
handler.post(new Runnable() {
public void run() {
setImageBitmap(BitmapFactory.decodeFile(cacheFile.getAbsolutePath()));
}
});
} catch (Exception e) {
Log.e(TAG, "setImageUrl error", e);
}
}
});
}
public void setImageUrl(final String url) {
Log.d(TAG, "load image,url:" + url);
ThreadPoolFactory.getInstance().execute(new Runnable() {
public void run() {
InputStream is = null;
try {
is = new URL(url).openStream();
final Bitmap bmp = BitmapFactory.decodeStream(is);
handler.post(new Runnable() {
public void run() {
setImageBitmap(bmp);
}
});
} catch (Exception e) {
Log.e(TAG, "setImageUrl error", e);
} finally {
IOUtils.closeQuietly(is);
}
}
});
}
}
2 楼
aa87963014
2010-08-24
你是在哪讨论的?
1 楼
zhs2472
2010-08-21
不错 很简练 学习了 期待有更精彩的深入研究
发表评论
-
启动动画
2010-05-19 13:46 1247<p>今天研究了下动画效果,我想做一个小图片,蹦蹦 ... -
好久没有整理博客了
2008-10-24 10:56 112好久没有整理博客了,今天浏览朋友博客时,看到一条alimama ... -
恋爱秘籍!!!
2007-07-27 18:45 2100追MM如猎,且为活猎,而后悦之,而后驯之。 下猎如饿虎之扑食也 ... -
恋爱笔记二
2007-07-21 10:57 721最近迷上《重庆森林》中一段音乐《California Drea ... -
恋爱笔记一
2007-07-20 18:42 727昨天和她谈了谈,感觉还好,只是遇到一个很难的问题,那就是两人之 ... -
心之轨迹
2007-07-19 18:07 551xombat 写到 有些事情是不能分析出来的,那就是感情. ... -
时间管理方法
2006-11-10 09:43 1468个人之所以成功,时间 ...
相关推荐
Android AsyncTask用法和异步加载图片通过AsyncTask 从网络上异步加载一张图片
Android 演示异步加载图片的实现 附源代码,这里主要是演示ListView的异步加载图片功能,异步加载一个view时,如果view里面有EditText,EditText在每次加载view都会触发焦点,这时候异步就会出错。可能我这样说不太...
如何异步加载图片,如果图片多了,这个脚本的效果还不错..
简洁 明确 listview异步加载图片
JS异步加载图片
iphone UITableView异步加载图片
使用Android Studio 练习RecyclerView 异步加载图片,解决图片乱序问题。
Android实现ListView异步加载图片
演化理解 Android 异步加载图片
实现异步加载图片。并点击图片实现缩放旋转功能,可以左右滑动换下张上张图片。
异步加载图片,之前的版本发现还是有问题,这次做了修改.上次忘记初始化,犯一低级错误。不好意思
以AJAX方式加载图片=异步加载图片,先显示个图片的占位图片 此技术常见于漫画网站.zip
iPhone上实现异步加载图片并缓存代码,供大家一起共同分享学习。
NULL 博文链接:https://laihuaiqing.iteye.com/blog/2169775
实现了异步加载图片进度条,代码更具有规范性
Android 异步加载图片缓存优化能异步加载图片,并缓存到本地,采用一级缓存,二级缓存和本地缓存,避免oom异常。源码中有详细注释,资料中有jar包,可以直接复制到项目中使用。
android listview异步加载图片实例 用到了线程池 下载的图片会保存到本地 并在数据库中保留记录 再次加载时会直接从本地读取
这是一个Android异步图片加载的例子
这是博文《异步加载图片(一)》对应的源码,这段代码仅实现了异步加载,对于滑动时暂停,停划时加载的问题会在《异步加载图片(二)》中讲解,这篇文章的地址:...
Android中实现异步加载图片的Demo,无论给定的图片地址是本地的还是网上URL地址,都能实现边读文件流边显示图片(文件尚未读完即在屏幕上开始显示了)。