- 浏览: 66734 次
- 性别:
- 来自: 湖北人在北京
最近访客 更多访客>>
文章分类
最新评论
-
手机测试:
我在使用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 1309<p>今天研究了下动画效果,我想做一个小图片,蹦蹦 ... -
好久没有整理博客了
2008-10-24 10:56 112好久没有整理博客了,今天浏览朋友博客时,看到一条alimama ... -
恋爱秘籍!!!
2007-07-27 18:45 2156追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 1524个人之所以成功,时间 ...
相关推荐
在WPF(Windows Presentation Foundation)应用开发中,异步加载图片是提高用户体验的关键技术,特别是在处理大尺寸或者网络延迟较大的情况下。本知识点将详细讲解如何实现wpf异步加载图片并在加载完成后显示。 ...
**懒加载(Lazy Load)异步加载图片技术详解** 懒加载是一种优化网页性能的技术,它主要应用于图片或者视频等大体积资源的加载。在网页初次加载时,只加载视口内的图片,当用户滚动页面,即将进入视口的图片才会被...
在Android开发中,异步加载图片是一项至关重要的技术,尤其对于那些包含大量图像的移动应用而言,如社交网络、电商应用等。异步加载能够提高用户体验,避免UI线程阻塞,防止应用出现"卡死"现象。在这个"Android异步...
本资料包主要讲解了如何使用`AsyncTask`进行异步加载图片,这对于在UI线程中保持流畅用户体验至关重要。 `AsyncTask`是Android SDK中的一个类,它为开发者提供了简单的多线程和回调功能。它的核心思想是将长时间...
在JavaScript(JS)中,异步加载图片是一种优化网页性能的技术。它允许浏览器在不影响页面主要功能的情况下,按需或后台加载非关键资源,如图片。这样可以减少页面初次加载的时间,提高用户体验,特别是对于含有大量...
然而,在实际开发中,当我们需要在RecyclerView中异步加载图片时,可能会遇到图片显示乱序的问题。本文将深入探讨这个问题及其解决方案。 首先,我们来理解为什么会出现图片乱序的现象。这是因为RecyclerView在滚动...
在iOS开发中,异步加载图片是一项至关重要的技术,它能显著提升应用的性能和用户体验。标题中的"iOS异步加载图片"暗示我们讨论的是如何在iOS应用中避免UI阻塞,通过后台线程加载图片资源,使得界面始终保持流畅。在...
为了解决这个问题,我们需要采用异步加载图片的策略。这就是“ListView异步加载图片”这一知识点的核心。 异步加载图片的目的是将耗时的操作(如网络请求、图片解码)从主线程分离到后台线程执行,从而保持用户界面...
因此,"iPhone UITableView异步加载图片"是解决这个问题的关键技术。 异步加载图片的基本思想是在主线程之外的其他线程(通常为后台线程)下载和处理图片,避免阻塞用户界面。在UITableView中,我们通常会在cell...
本篇文章将深入探讨如何在Android中实现ListView异步加载图片,主要涉及以下几个关键知识点: 1. **AsyncTask**:Android提供了AsyncTask类,用于在后台线程执行耗时操作,并在UI线程更新结果。在图片加载场景中,...
在IT行业中,网络异步加载图片的轮播图是一种常见的用户界面组件,广泛应用于网站、APP等场景,用于展示多张图片并实现自动或手动切换。在这个特定的【标题】"网络异步加载图片的轮播图带点击方法"中,我们可以深入...
接下来,我们讨论核心主题——异步加载图片。在iOS应用中,直接在主线程上加载网络图片会阻塞用户界面,导致应用程序响应变慢,影响用户体验。因此,异步加载成为最佳实践。IconDownloader是一个用于异步下载和缓存...
在网页开发中,异步加载图片(以AJAX方式加载图片)是一种常见的优化技术,尤其在处理大量图片的场景下,比如漫画网站。通过这种方式,可以显著提高页面加载速度,提升用户体验。AJAX(Asynchronous JavaScript and ...
在Android应用开发中,异步加载图片是一项常见的需求,特别是在处理大数据量的图像时,如在GridView或ListView中展示图片。`AsyncTask`是Android提供的一种轻量级的多线程解决方案,它允许开发者在后台执行耗时操作...
Android 演示异步加载图片的实现 附源代码,这里主要是演示ListView的异步加载图片功能,异步加载一个view时,如果view里面有EditText,EditText在每次加载view都会触发焦点,这时候异步就会出错。可能我这样说不太...
在Android应用开发中,异步加载图片是一项至关重要的任务,特别是在处理大量图片或者网络图片时。这不仅可以提高用户体验,避免因加载图片导致的界面卡顿,还能有效地节省系统资源。本教程将深入探讨如何在Android中...
在处理大量图片时,为了提升用户体验和优化性能,通常会采用异步加载图片的技术。本文将深入探讨如何实现ListView中图片的异步加载,并结合进度条显示加载状态,使代码更加规范。 一、异步加载图片的重要性 在...
"Android异步加载图片"是一个常见的需求,它涉及到用户体验优化、内存管理以及线程安全等多个方面。这里我们将深入探讨这个主题,并结合提供的"ImageLoader-develop"可能是一个图片加载库的源码,来讲解相关的知识点...
在Android开发中,异步加载图片是一项至关重要的技术,它能显著提升用户体验,尤其是在处理大量图片数据时。这个"Android中实现异步加载图片的Demo"展示了如何在Android应用中高效地加载和显示图片,无论是从本地...