安卓中的AsyncTask(异步任务) (下)

来源:互联网 发布:使用excel制作数据库 编辑:程序博客网 时间:2024/06/06 01:50

之前写了异步任务的上篇,简单介绍了一下异步任务的几个方法,今天写的是如何使用异步任务从网络上下载一张图片,并实时显示下载的进度。


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>


2) 在.java文件中,使用到AsyncTask,在doInBackground 方法中,使用HttpURLConnection来实现下载图片的逻辑,这部分内容属于网络连接的内容,会在以后的文章来说明,所有代码几乎都写了注释。由于我们下载的是一张图片,三个泛型参数中第一个是下载的URL地址;由于要实时显示下载进度,第二个参数为Integer;下载完成返回的是一张图片,类型为Bitmap。

以下为.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";@Overrideprotected 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() {@Overridepublic 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(); // 获取网络连接的对象connectionconnection.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下载图片的所有内容,异步任务的功能非常强大,大家有兴趣可以去查找相关书籍来学习。



0 0
原创粉丝点击