之前写了异步任务的上篇,简单介绍了一下异步任务的几个方法,今天写的是如何使用异步任务从网络上下载一张图片,并实时显示下载的进度。
1) 首先是XML文件,布局简单,一个按钮,一个用于显示图片的ImageView
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.zhixing.asynctaskprogress.MainActivity" >
<Button
android:id="@+id/btn_start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="60dp"
android:layout_marginRight="60dp"
android:layout_marginTop="30dp"
android:text="下载图片" />
<ImageView
android:id="@+id/image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:src="@drawable/ic_launcher"
/>
</LinearLayout>
以下为.java的所有代码:
package com.zhixing.asynctaskprogress;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.zhixing.asynctaskprogress002.R;
public class MainActivity extends Activity {
private Button btn_start;
private ImageView image;
private MyAsyncTask asyncTask;
private ProgressDialog progressDialog; // ProgressDialog: 进度条对话框
private String url = "http://www.benbenla.cn/images/20110731/benbenla-09c.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image = (ImageView) findViewById(R.id.image);
btn_start = (Button) findViewById(R.id.btn_start);
progressDialog = new ProgressDialog(this);
progressDialog.setTitle("提示");
progressDialog.setMessage("正在下载,请稍后...");
// 设置进度条对话框的样式,ProgressDialog.STYLE_HORIZONTAL: 设置进度条为水平
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
btn_start.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
asyncTask = new MyAsyncTask();
asyncTask.execute(url); // 通过execute()方法调用AsyncTask,参数传入网络图片的地址
}
});
}
class MyAsyncTask extends AsyncTask<String, Integer, Bitmap> {
@Override // 该方法是在后台任务执行之前被UI线程调用,做的是界面的初始化操作,比如显示一个进度条
protected void onPreExecute() {
super.onPreExecute();
progressDialog.show();
}
@Override // 所有的耗时任务都在该方法执行
protected Bitmap doInBackground(String... params) {
Bitmap bitmap = null;
URL url;
HttpURLConnection connection = null;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
// new一个URL对象,并传入需要的网络地址;
url = new URL(params[0]); // params是一个可变长数组,可以接受传入的多个参数,params[0]代表的是我们要下载的图片的地址
connection = (HttpURLConnection) url.openConnection(); // 获取网络连接的对象connection
connection.setConnectTimeout(5 * 1000); // 设置连接超时的时间,单位毫秒
connection.setReadTimeout(5 * 1000); // 设置读取超时的时间,单位毫秒
connection.setRequestMethod("GET"); // 设置请求的方式,参数可以是GET,或者POST,但必须要大写
InputStream in = connection.getInputStream(); // 通过 HttpURLConnection 对象的 getInputStream() 方法 获取到输入流
// BufferedInputStream: 缓冲输入流, 通过BufferedInputStream对我们获取到的输入流进行包装,提高读取的效率
BufferedInputStream bis = new BufferedInputStream(in);
int length = connection.getContentLength(); // 下载文件的总长度
int len = 0; // 读取的字节总数
int count = 0; // 当前进度值
byte[] buffer = new byte[128]; // []里面的数字代表每次读取的字节数,数值越小,下载速度越慢
while((len = bis.read(buffer)) != -1){ // 不等于-1代表没有读完,bis.read(buffer): 将流读到 BufferedInputStream 中
count += len;
int num = (int) ((count/(float)length)*100); // num: 要显示的当前进度条数值
publishProgress(num); // 调用publishProgress方法来更新进度条数值
outputStream.write(buffer,0,len); // 将流写到ByteArrayOutputStream(字节数组流)中
}
byte[] result = outputStream.toByteArray(); // 获取内存缓冲区的数据,转换成字节数组
bitmap = BitmapFactory.decodeByteArray(result, 0, result.length); // 将字节数组解析成Bitmap
in.close(); // 使用完,要记得关闭流
bis.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect(); // 断开连接
}
}
return bitmap; // 返回 Bitmap
}
@Override // 该方法在publishProgress方法被调用之后,被UI线程调用,用来在界面上显示任务的进展情况,比如通过一个进度条来显示进度
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
progressDialog.setProgress(values[0]);
}
@Override // 在doInBackground方法执行完之后,该方法江北UI线程调用,后台任务的结果将通过该方法传到UI线程,比如提示用户下载完成等等
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
progressDialog.dismiss(); // 让进度条对话框消失
image.setImageBitmap(result); // 设置从网络下载的图片
Toast.makeText(MainActivity.this, "下载完成", Toast.LENGTH_SHORT).show();
}
}
}
下载过程中的截图:
完成后的的截图:
以上就是关于AsyncTask下载图片的所有内容,异步任务的功能非常强大,大家有兴趣可以去查找相关书籍来学习。