1、使用异步任务加载网络上的图片
我们可以打开这个网址: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 @Override10 protected void onPostExecute (Drawable result) {11 super.onPostExecute(result);12 mDialog.dismiss();13 mImage.setImageDrawable(result);14 }15 16 @Override17 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 @Override22 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 @Override37 protected Drawable doInBackground (Void... params) {38 String url = "http://img1.3lian.com/img2011/07/20/05.jpg";39 return loadImages(url);40 }41 42 @Override43 protected void onPostExecute (Drawable result) {44 super.onPostExecute(result);45 mDialog.dismiss();46 mImage.setImageDrawable(result);47 }48 49 @Override50 protected void onPreExecute () {51 super.onPreExecute();52 mDialog.show();53 }54 }55 56 @Override57 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的时候,在加载图片但是图片还没有加载出来的时候:
另外需要注意的是,需要在manifest里面加入链接网络的权限:
1 <uses-permission android:name="android.permission.INTERNET"/>
另外在onDestory()的时候要把progressDialog dismiss掉,不让在退出应用程序的时候会报错。
2、按返回键暂停异步任务
使用AsynTask异步任务处理耗时操作(work)时,通常会增加ProgressDialog进度条来显示等待操作(或加载进度)。
此时按返回键,因为焦点在ProgressDialog上,ProgressDialog捕获返回键操作,而Activity是不响应返回键操作的。
如果你想实现,当进行耗时操作时(ProgressDialog正在显示),按返回键,结束当前work操作。
你需要注意ProgressDialog的设置:
progress_dialog.setCancelable(true);//响应取消操作,这里如果设置false,按返回键ProgressDialog也不消失。
progress_dialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
AsynTask.this.cancle(true);//执行异步线程取消操作
}
});
同时注意,AsynTask执行cancele()操作后,相应的方法是如何执行。
You can stop a running task with cancel(true). A cancel will let the task finish its doInBackground but will never call onPostExecute. You could interrupt your background routine by checking isCanceled() and so return earlier since the task was killed.