使用 AsyncTask 加载图像
我正在尝试创建一个自定义列表适配器,其中包含需要从互联网下载的每个项目的图像。当我第一次进入活动时 - 应用程序冻结一段时间,直到下载图像,然后加载活动列表。
据我所知,图像是在活动加载之前下载的。活动加载后如何下载图像。我想我需要使用异步任务。但由于我正在自定义阵列适配器中加载图像,因此不知道该怎么做。
这是我的自定义适配器的 getView()
:
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.list_item_default, null);
}
Item p = items.get(position);
if (p != null) {
TextView list_title = (TextView) v.findViewById(R.id.list_title);
TextView list_description = (TextView) v
.findViewById(R.id.list_description);
TextView list_timestamp = (TextView) v
.findViewById(R.id.list_timestamp);
ImageView list_image = (ImageView) v.findViewById(R.id.list_image);
if (list_title != null) {
list_title.setText(p.getItemTitle());
}
if (list_description != null) {
list_description.setText(p.getItemDescription());
}
if (list_timestamp != null) {
list_timestamp.setText(p.getItemTimestamp());
}
if (list_image != null) {
Log.d("bMobile", "inside getView() image");
try {
URL imageURL = new URL(p.getItemImage());
HttpURLConnection con = (HttpURLConnection) imageURL
.openConnection();
InputStream inputStrem = con.getInputStream();
Bitmap image = BitmapFactory.decodeStream(inputStrem);
if (null != image)
list_image.setImageBitmap(image);
else
Log.d("bMobile", "Bitmap is Null");
} catch (Exception e) {
}
}
}
return v;
}
AsyncTask:
public class DownloadImagesTask extends AsyncTask<ImageView, Void, Bitmap> {
ImageView imageView = null;
@Override
protected Bitmap doInBackground(ImageView... imageViews) {
this.imageView = imageViews[0];
return download_Image((String)imageView.getTag());
}
@Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}
}
private Bitmap download_Image(String url) {
Bitmap bmp =null;
try{
URL ulrn = new URL(url);
HttpURLConnection con = (HttpURLConnection)ulrn.openConnection();
InputStream is = con.getInputStream();
bmp = BitmapFactory.decodeStream(is);
if (null != bmp)
return bmp;
}catch(Exception e){}
return bmp;
}
I am trying to create a custom List Adapter which has an Image for every item it needs to download from the internet. When I first enter the Activity - the app freezes for a while till the images are downloaded and then the Activity List is loaded.
As I can make out the images are being downloaded before the activity loads. How can I download the images after the activity has loaded. I think I need to use Async Task. But since I am loading the images in the Custom Array Adapter not sure how to do it.
This is my Custom Adapter's getView()
:
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi;
vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.list_item_default, null);
}
Item p = items.get(position);
if (p != null) {
TextView list_title = (TextView) v.findViewById(R.id.list_title);
TextView list_description = (TextView) v
.findViewById(R.id.list_description);
TextView list_timestamp = (TextView) v
.findViewById(R.id.list_timestamp);
ImageView list_image = (ImageView) v.findViewById(R.id.list_image);
if (list_title != null) {
list_title.setText(p.getItemTitle());
}
if (list_description != null) {
list_description.setText(p.getItemDescription());
}
if (list_timestamp != null) {
list_timestamp.setText(p.getItemTimestamp());
}
if (list_image != null) {
Log.d("bMobile", "inside getView() image");
try {
URL imageURL = new URL(p.getItemImage());
HttpURLConnection con = (HttpURLConnection) imageURL
.openConnection();
InputStream inputStrem = con.getInputStream();
Bitmap image = BitmapFactory.decodeStream(inputStrem);
if (null != image)
list_image.setImageBitmap(image);
else
Log.d("bMobile", "Bitmap is Null");
} catch (Exception e) {
}
}
}
return v;
}
AsyncTask:
public class DownloadImagesTask extends AsyncTask<ImageView, Void, Bitmap> {
ImageView imageView = null;
@Override
protected Bitmap doInBackground(ImageView... imageViews) {
this.imageView = imageViews[0];
return download_Image((String)imageView.getTag());
}
@Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}
}
private Bitmap download_Image(String url) {
Bitmap bmp =null;
try{
URL ulrn = new URL(url);
HttpURLConnection con = (HttpURLConnection)ulrn.openConnection();
InputStream is = con.getInputStream();
bmp = BitmapFactory.decodeStream(is);
if (null != bmp)
return bmp;
}catch(Exception e){}
return bmp;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
“应用程序冻结” - 这是因为您正在事件线程或 UI 线程上下载图像。你绝对不应该这样做。所有阻塞操作、长时间运行的操作、网络操作,都应该在单独的线程上运行。是的,您可以使用 asynctask 来加载图像,这应该可以解决问题。
您可以采取两个选项来解决该问题:
使用 droid fu 库中的 WebImageView http://brainflush.wordpress.com/2009/11/23/droid-fu-part-2-webimageview-and-webgalleryadapter/
WebImageView 也使用缓存,因此您无需再次下载已经下载的图像。下载图像成本高昂且消耗数据。
我使用 WebImageView 并能够加载列表中的图像。我只花了大约 20 分钟就让它全部工作起来,所以你知道集成它很容易。
第二个选项是使用异步任务。请检查 Android:使用 Asynctask 从 Web 加载图像。 stackoverflow 中有更多关于如何执行此操作的信息。
任何时候你的 UI 挂起,你都会有一种令人毛骨悚然的感觉,你正在 UI 线程上做一些事情。
"the app freezes" - This is because you are downloading the images on the event thread or UI Thread. You should never do that. All blocking operations,long running operations, network operations, should be run on a separate thread. Yes you can use asynctask to do the image loading which should fix the issue.
Two options you can do to solve the issue is
Use WebImageView from droid fu library at http://brainflush.wordpress.com/2009/11/23/droid-fu-part-2-webimageview-and-webgalleryadapter/
WebImageView uses caching as well so you dont need to download images again which you have already downloaded. Downloading images are expensive and consume data.
I used WebImageView and was able to load images in list. It took me just about 20 mins to get it all working, so you know its easy integrating it.
Second option is to use async task . Please check Android : Loading an image from the Web with Asynctask . There are lot more info in stackoverflow regarding how to do this.
Any time your UI hangs, you should have a creepy feeling, that you are doing something on the UI thread.