参考疯狂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_EXECUTOR和THREAD_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