AsyncTask 异步任务

参考疯狂Android讲义3.6章:


AsyncTask<Params,Progress,Result> 抽象类,三个泛型参数:

Params:启动任务执行的输入参数类型;

Progress:后台任务完成的进度值的类型;

Result:后台任务执行后返回的结果类型;

不需要指定类型的话用Void。


必须要继承重写的方法是:

doInBackground(Params... param):后台线程要完成的任务;可以在该方法中调用publishProgress(Progress... values)方法更新任务执行的进度。


下边例子还用到的方法:

onProgressUpdate(Progress... values):如果在doInBackground方法中调用publishProgress方法,则会触发该方法;

onPreExecute():在执行后台任务之前调用该方法,通常执行一些初始化工作,如在界面上显示进度条;

onPostExecute(Result result):doInBackground方法执行完后将执行该方法,并将返回值作为参数传入该方法;


调用AsyncTask对象时,必须在UI线程中实例化对象,然后执行execute方法,开始后台任务。


注意事项:

上边提到的4个方法,都应该由Android系统负责调用。程序员只能调用实例对象的execute方法。

另外execute方法只能被执行一次,多次调用会报错:

E/AndroidRuntime(3226): Caused by: java.lang.IllegalStateException: Cannot execute task: the task is already running.




crazy Android 给的示例:

package org.crazyit.handler;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.view.View;
import android.widget.TextView;

/**
 * Description: <br/>
 * site: <a href="http://www.crazyit.org">crazyit.org</a> <br/>
 * Copyright (C), 2001-2014, Yeeku.H.Lee <br/>
 * This program is protected by copyright laws. <br/>
 * Program Name: <br/>
 * Date:
 * @author Yeeku.H.Lee kongyeeku@163.com
 * @version 1.0
 */
public class AsyncTaskTest extends Activity
{
	private TextView show;

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		show = (TextView) findViewById(R.id.show);
	}

	// 重写该方法,为界面的按钮提供事件响应方法
	public void download(View source) throws MalformedURLException
	{
		DownTask task = new DownTask(this);
		task.execute(new URL("http://www.so.cn"));
	}

	class DownTask extends AsyncTask<URL, Integer, String>
	{
		// 可变长的输入参数,与AsyncTask.exucute()对应
		ProgressDialog pdialog;
		// 定义记录已经读取行的数量
		int hasRead = 0;
		Context mContext;

		public DownTask(Context ctx)
		{
			mContext = ctx;
		}

		@Override
		protected String doInBackground(URL... params)
		{
			StringBuilder sb = new StringBuilder();
			try
			{
				URLConnection conn = params[0].openConnection();
				// 打开conn连接对应的输入流,并将它包装成BufferedReader
				BufferedReader br = new BufferedReader(
					new InputStreamReader(conn.getInputStream()
					, "utf-8"));
				String line = null;
				while ((line = br.readLine()) != null)
				{
					sb.append(line + "\n");
					hasRead++;
					publishProgress(hasRead);
				}
				return sb.toString();
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(String result)
		{
			// 返回HTML页面的内容
			show.setText(result);
			pdialog.dismiss();
		}

		@Override
		protected void onPreExecute()
		{
			pdialog = new ProgressDialog(mContext);
			// 设置对话框的标题
			pdialog.setTitle("任务正在执行中");
			// 设置对话框 显示的内容
			pdialog.setMessage("任务正在执行中,敬请等待...");
			// 设置对话框不能用“取消”按钮关闭
			pdialog.setCancelable(true);
			// 设置该进度条的最大进度值
			pdialog.setMax(100);
			// 设置对话框的进度条风格
			pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
			// 设置对话框的进度条是否显示进度
			pdialog.setIndeterminate(true);
			pdialog.show();
		}

		@Override
		protected void onProgressUpdate(Integer... values)
		{
			// 更新进度
			show.setText("已经读取了【" + values[0] + "】行!");
			pdialog.setProgress(values[0]);
		}
	}
}

值得注意的是AndroidManifest.xml文件中需要加上访问Internet URL的权限:

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





More about AsyncTask:

Android3.0之前,异步任务的线程池介绍:

http://www.linuxidc.com/Linux/2011-09/43150.htm

1、线程池中的工作线程少于5个时,将会创建新的工作线程执行异步任务

2、线程池中已经有5个线程,缓冲队列未满,异步任务将会放到缓冲队列中等待

3、线程池中已经有5个线程,缓冲队列已满,那么线程池将新开工作线程执行异步任务

4、线程池中已经有128个线程,缓冲队列已满,如果此时向线程提交任务,将会抛出RejectedExecutionException


5个以内的线程可以同步进行,6-15会放入缓冲队列,16-128以上会新开启新的工作线程。128以上会抛出异常。


3.0之后的异步任务线程池添加了新增了接口#executeOnExecutor(),可以自定义线程池。新增了二个预定义的线程池SERIAL_EXECUTORTHREAD_POOL_EXECUTOR

1、executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)就跟2.3版本的AsyncTask.execute()效果是一样的

2、默认AsyncTask.execute()会一个接一个任务进行,不会同时进行,也就SERIAL_EXECUTOR

3、如果你想让所有的任务都能并发同时运行,那就创建一个没有限制的线程池(Executors.newCachedThreadPool())

http://blog.csdn.net/hitlion2008/article/details/7983449

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值