Android异步操作----AsyncTask类

在开发Android应用程序时必须遵守单线程模型的原则,尤其是开发有网络交互功能的应用,Android UI线程主要用来控制控件和触屏的操作。在单线程模型中必须要遵行两条原则:

1、 不要阻塞UI线程;

2、 确保只在UI线程中访问Android UI工具包

当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的时间,例如:用户的按键事件,用户接触屏幕的事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。

AsyncTask其实是Android开发包提供的一个工具类,它使创建需要与用户界面交互的长时间运行的任务变得更简单。相对来说AsyncTask更轻量级一些,适用于简单的异步处理,不需要借助线程和Handler即可实现。

AsyncTask是抽象类,它定义了三种泛型类型,即AsyncTask中有三个参数(例如class MyTask extends AsyncTask<参数1 , 参数2 ,参数3>{}):

参数1:向后台任务的执行方法传递参数的类型;

参数2:在后台任务执行过程中,要求主UI线程处理中间状态,通常是一些UI处理中传递的参数类型;

参数3:后台任务执行完返回时的参数类型。

其中参数1和参数2是一个泛型参数,即可变数组参数,例如String…,相当于String[]。传参数时可传可不传,传的话可以使一个个并列地传,也可以直接是一个数组。

AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该有程序调用,开发者需要重写这些方法:

1、 实例化AsyncTask:

MyTask task = new MyTask(this);

2、实现AsyncTask中定义的如下方法,下面是按照执行顺序列出的:

1)、onPreExecute():运行于UI线程,该方法将在执行实际的后台操作前被调用。可以在该方法中做一些准备工作,例如在界面上显示一个进度条反映当前任务执行的进度;

2)、doInBackground(Params…):该方法运行在后台线程中,主要负责执行那些很耗时的后台计算下载工作,也是使用AsyncTask必须重写的一个方法。我们可以在其中调用publishProgress方法来更新任务的进度。

3)、onProgressUpdate(Progress…):运行于UI线程,在publishProgress方法被调用后执行,将任务进度显示在界面上;

4)、onPostExecute():运行于UI线程,顾名思义,该方法在doInBackground执行完后,后台的计算结果将通过该方法传递到UI线程;

5)、onCancelled():运行于UI线程,该方法也可以不重写,主要用来当用户按取消按钮后,退出后台任务使用。

为了正确的使用AsyncTask类,以下是几条必须遵守的准则:

1、 Task的实例化必须在UI线程中创建;

2、 Execute方法必须在UI线程中调用;

3、 不要手动调用onPreExecute()、onPostExecute(Result)、doInBackground(Params…)、onProgressUpdate(Progress)这几个方法;

4、 该Task只能被执行一次,否则多次调用时将会出现异常

注意:Task只能被执行一次,也就是说只能调用一次Task.execute()方法,如果想再次调用,必须重新实例化这个类。

下面来看一个具体例子,从网上下载一张图片并显示:

1、创建DownloadPicture类继承AsyncTask:

package com.example.test02;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;

public class DownloadPicture extends AsyncTask<String, Integer, Bitmap>
{
	private DownloadCallBack downloadCallBack;
	
	public DownloadPicture(DownloadCallBack downloadCallBack ) 
	{
		this.downloadCallBack = downloadCallBack;
	}
	
	//创建一个回调接口,用于在子线程执行时调回主线程,执行自定义操作
	public interface DownloadCallBack
	{
		public void DoInPre();
		
		public void Doing(int length , int max);
		
		public void DoInFinish(Bitmap bitmap);
	}
	
	
	@Override
	protected void onPreExecute() 
	{
		downloadCallBack.DoInPre();
		super.onPreExecute();
	}
	
	@Override
	protected Bitmap doInBackground(String... params) 
	{
		try 
		{
			URL url = new URL(params[0].toString());
			HttpURLConnection connection = (HttpURLConnection)url.openConnection();
			connection.setConnectTimeout(5000);
			int max = connection.getContentLength();
			InputStream inputStream = connection.getInputStream();
			ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int length = 0;
			int total = 0;
			while ((length = inputStream.read(buffer)) != -1) 
			{
				arrayOutputStream.write(buffer, 0, length);
				total += length;
				//发送数据,更新下载进度
				publishProgress(total , max);
				Thread.sleep(100);
			}
			byte[] result = arrayOutputStream.toByteArray();
			return BitmapFactory.decodeByteArray(result, 0, result.length);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		
		return null;
	}
	
	@Override
	protected void onProgressUpdate(Integer... values) 
	{
		Log.i("输出", "onProgressUpdate..." + values[0]);
		downloadCallBack.Doing(values[0] , values[1]);
		super.onProgressUpdate(values);
	}
	
	@Override
	protected void onPostExecute(Bitmap result) 
	{
		downloadCallBack.DoInFinish(result);
		super.onPostExecute(result);
	}
	
	@Override
	protected void onCancelled() 
	{
		downloadCallBack.DoInFinish(null);
		super.onCancelled();
	}
}


2、实例化DownloadPicture,并执行:

downloadPicture = new DownloadPicture(new downloadCallBack());
		downloadPicture.execute("http://ww3.sinaimg.cn/mw600/656254f3jw1dylafmgiaqj.jpg");  


3、编辑匿名内部类downloadCallBack:

private class downloadCallBack implements DownloadCallBack
	{

		public void DoInPre() 
		{
			dialog = new ProgressDialog(MainActivity.this);
			dialog.setButton("取消", new DialogInterface.OnClickListener()
			{
				public void onClick(DialogInterface arg0, int arg1) 
				{
					downloadPicture.cancel(true);
					dialog.dismiss();
				}
			});
			dialog.setCancelable(true);
			dialog.setTitle("正在下载...");
			dialog.setMessage("正在下载图片...");
			dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			dialog.show();
		}

		public void Doing(int length , int max) 
		{
			Log.i("输出", "Doing..." + length);
			dialog.setMessage((int)((length/(float)max)*100) + "");
			dialog.setProgress((int)((length/(float)max)*100));
		}

		public void DoInFinish(Bitmap bitmap) 
		{
			dialog.dismiss();
			if (bitmap != null) 
			{
				imageView.setImageBitmap(bitmap);
			}
		}


大功告成,运行即可,下面是截图和源码下载地址:

源码下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值