锁定老帖子 主题:异步加载图片
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-08-20
前几天记得说要分享一下异步下载加载图片的经验,最近一直在研究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张左右必报。坛子里也讨论了许久,没有结果,都是缩放图片或者避开这个大量图片的问题。我就采用的是避开大量图片的方法。过几天再写出来
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-08-21
不错 很简练 学习了 期待有更精彩的深入研究
|
|
返回顶楼 | |
发表时间:2010-08-24
你是在哪讨论的?
|
|
返回顶楼 | |
发表时间: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); } } }); } } |
|
返回顶楼 | |
发表时间:2010-08-24
ls 和我的做法一样 保存到本地。
File dir = cacheFile.getParentFile(); if (!dir.exists()) { dir.mkdirs(); } 这个判断 我那到其他地方去了,就不用每次都判断一次。 ThreadPoolFactory 线程池? 我对这个不太熟悉 有什么特别的好处吗? 你是怎么实现的? 还有 我的 imageView 在listView里面 下载完之后 还要更新视图 感觉有点怪怪的。 不知道 有没什么好的方法 |
|
返回顶楼 | |
发表时间:2010-08-24
学android居然没有加入组织。落后了啊
搜索下hong老大的坛子。 |
|
返回顶楼 | |
发表时间:2010-08-24
aa87963014 写道 ls 和我的做法一样 保存到本地。
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); } } |
|
返回顶楼 | |
发表时间: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); } } } |
|
返回顶楼 | |
发表时间:2010-08-25
圈子加了是加了。但是好像不是很活跃。
坛子?圈子? 还是 q q 群? |
|
返回顶楼 | |
发表时间:2010-08-29
我也发现了内存溢出的情况,请要怎么去处理呀!
|
|
返回顶楼 | |