使用异步任务加载网络上的图片

使用异步任务加载网络上的图片

  我们知道,如果要加载一个很耗时的操作,会阻塞主线程,这时我们可以想到开启一个新的线程,避免阻塞,在android中也有这样的问题,我们可以用异步任务来操作,异步任务也是开启一个线程,线程里面发一个消息,然后通知去改变UI。

  废话不多说,我们先看一个例子:我们可以打开这个网址:http://img1.3lian.com/img2011/07/20/05.jpg可以看到一副很好看的图片,我们就要把这个图片显示出来,首先,还是先要布局,我们要显示一幅图片,所以我们的布局中需要一个ImageView,布局很简单,一个ImageView就可以了:

  

复制代码
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout
 3   xmlns:android="http://schemas.android.com/apk/res/android"
 4   android:layout_width="match_parent"
 5   android:layout_height="match_parent">
 6     <ImageView 
 7       android:id="@+id/img" 
 8       android:scaleType="fitXY"
 9       android:layout_width="match_parent" 
10       android:layout_height="match_parent"/>
11 </LinearLayout>
复制代码

 之后我们要写一个Activity显示这个图片,不过要加载网络上的图片,我们需要从一个URL的流中获取这个图片,所以我们要写一个方法来获取这张图片:

  

复制代码
1 public Drawable loadImages(String url) { 
2         try {
3             return Drawable.createFromStream((InputStream)(new URL(url)).openStream(), "test");
4         }
5         catch (IOException e) {
6             e.printStackTrace();
7         }
8         return null;
9     }
复制代码

  从URL中打开流,强制转换成InputStream,然后从流中拿到Drawable。

  既然可以获取图片了,我们要考虑一个问题,如果图片很大,加载的很慢怎么办,我们岂不是要等很久?不要紧,这时候我们就可以用异步任务了。

  首先我们要写一个内部类,这个类部类是继承自异步任务的,需要重载里面的doBackGround方法:

  

复制代码
 1  private class ImageAsynTask extends AsyncTask<Void, Void, Drawable> {
 2 
 3         @Override
 4         protected Drawable doInBackground (Void... params) {
 5             String url = "http://img1.3lian.com/img2011/07/20/05.jpg";
 6             return loadImages(url);
 7         }
 8         
 9         @Override
10         protected void onPostExecute (Drawable result) {
11             super.onPostExecute(result);
12             mDialog.dismiss();
13             mImage.setImageDrawable(result);
14         }
15         
16         @Override
17         protected void onPreExecute () {
18             super.onPreExecute();
19             mDialog.show();
20         }
21     }
复制代码

 首先看这个方法:onPreExecute()这个方法是在doInBackGround前面执行。我们把这个方法写出来,我们需要在获取图片之前等待的时间里,写一个progressDialog,显示出来,提示用户,目前正在加载图片,需要等待一段时间。同时在后台操作doBackGround运行。

  在doBackGround完成之后就会执行onPostExecute(Drawable result)方法,看这个方法就知道,必须在doBackGround完成之后,把得到的结果Drawable作为参数传到onPostExecute方法里面去,执行这个方法就表示已经加载完了,我们需要将progressDialog消失掉,然后把图片显示出来就可以了,整个过程很简单。

  看下整个Activity的代码:

  

复制代码
 1 package com.test.asyntask;
 2 
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 import java.net.URL;
 6 
 7 import android.app.Activity;
 8 import android.app.ProgressDialog;
 9 import android.graphics.drawable.Drawable;
10 import android.os.AsyncTask;
11 import android.os.Bundle;
12 import android.widget.ImageView;
13 
14 import com.test.R;
15 
16 public class AsynTask extends Activity {
17     
18     private ImageView mImage;
19     private ProgressDialog mDialog;
20     
21     @Override
22     protected void onCreate (Bundle savedInstanceState) {
23         super.onCreate(savedInstanceState);
24         setContentView(R.layout.asyn_task);
25         
26         mDialog = new ProgressDialog(this);
27         mDialog.setTitle("请稍等");
28         mDialog.setMessage("正在加载...");
29         
30         mImage = (ImageView) findViewById(R.id.img);
31         new ImageAsynTask().execute();
32     }
33     
34     private class ImageAsynTask extends AsyncTask<Void, Void, Drawable> {
35 
36         @Override
37         protected Drawable doInBackground (Void... params) {
38             String url = "http://img1.3lian.com/img2011/07/20/05.jpg";
39             return loadImages(url);
40         }
41         
42         @Override
43         protected void onPostExecute (Drawable result) {
44             super.onPostExecute(result);
45             mDialog.dismiss();
46             mImage.setImageDrawable(result);
47         }
48         
49         @Override
50         protected void onPreExecute () {
51             super.onPreExecute();
52             mDialog.show();
53         }
54     }
55     
56     @Override
57     protected void onDestroy () {
58         super.onDestroy();
59         mDialog.dismiss();
60     }
61     
62     public Drawable loadImages(String url) { 
63         try {
64             return Drawable.createFromStream((InputStream)(new URL(url)).openStream(), "test");
65         }
66         catch (IOException e) {
67             e.printStackTrace();
68         }
69         return null;
70     }
71 }
复制代码

 运行一下,看下效果:

  1.显示progressDialog的时候,在加载图片但是图片还没有加载出来的时候:

  

  2.看一下显示出来的图片吧:

  

 可以看到,加载完成后,图片可以显示出来了。

  另外需要注意的是,需要在manifest里面加入链接网络的权限:

  

1 <uses-permission android:name="android.permission.INTERNET"/>

  另外在onDestory()的时候要把progressDialog dismiss掉,不让在退出应用程序的时候会报错。

  好了就到这儿吧,外面打很大的雷,估计下雨了吧,我还没带伞呢,哎,又得淋雨回去了啊。。。。悲惨啊。。。

  哦,对了,把源代码传上来吧,里面的内容很多,都是写的例子程序,在com.test.asyntask包里面。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值