类概述
AsyncTask能够适当地、简单地用于 UI线程。这个类不需要操作线程(Thread)就可以完成后台操作将结果返回UI。
异步任务的定义是一个在后台线程上运行,其结果是在 UI线程上发布的计算。
异步任务被定义成三种泛型类型: Params,Progress和 Result;
和四个步骤: begin , doInBackground,processProgress 和end。
AsyncTask的泛型类型
这三个类型被用于一个异步任务,如下:
1. Params,启动任务执行的输入参数
2. Progress,后台任务执行的百分比
3. Result,后台计算的结果类型
在一个异步任务里,不是所有的类型总被用。
假如一个类型不被使用,可以简单地使用 Void类型
AsyncTask的4个步骤
当一个异步任务被执行,任务经过四各步骤:
1.onPreExecute(),在UI线程上调用任务后立即执行。
这步通常被用于设置任务,例如在用户界面显示一个进度条。
2.doInBackground(Params...),后台线程执行onPreExecute()完后立即调用。
这步被用于执行较长时间的后台计算。异步任务的参数也被传到这步。
计算的结果必须在这步返回,将传回到上一步。
在执行过程中可以调用publishProgress(Progress...)来更新任务的进度。
3.onProgressUpdate(Progress...),一次呼叫 publishProgress(Progress...)后调用 UI线程。
执行时间是不确定的。这个方法用于当后台计算还在进行时在用户界面显示进度。
例如:这个方法可以被用于一个进度条动画或在文本域显示记录。
4.onPostExecute(Result), 当后台计算结束时,调用 UI线程。
后台计算结果作为一个参数传递到这步。
AsyncTask的线程规则
有一些线程规则必须去遵守,这个类才会正确的工作:
1. 任务实例必须创建在 UI线程
2. execute(Params...)必须在 UI线程上调用
3. 不要手动调用onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...)
4. 这个任务只执行一次(如果执行第二次将会抛出异常)
AsyncTask使用的注意点
AsyncTask一定要在Ui所在的主线程中创建;
不要手工调用它的四个函数;
只能execute一次;
AsyncTask的应用实例
Activity文件
- package com.app.myhandler;
-
- import android.app.Activity;
- import android.os.AsyncTask;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.ProgressBar;
- import android.widget.TextView;
-
- public class AsyncTaskDemo extends Activity implements OnClickListener {
-
- private TextView textView1;
- private Button button1;
- private ProgressBar progressBar1;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_asynctask);
-
- progressBar1 = (ProgressBar)findViewById(R.id.progressBar1);
- button1 = (Button)findViewById(R.id.button1);
- textView1 = (TextView)findViewById(R.id.textView1);
-
- button1.setOnClickListener(this);
- }
-
- @Override
- public void onClick(View v) {
- if(button1.getText().equals("开始")) {
- setTitle("正在下载...");
- new MyTask().execute(1);
- }
- }
-
- boolean flag = true;
-
- @SuppressWarnings("unused")
- private class MyTask extends AsyncTask<Integer, Integer, String> {
- int i = 0;
- @Override
- protected void onPreExecute() {
- button1.setEnabled(false);
- super.onPreExecute();
- }
-
- @Override
- protected String doInBackground(Integer... params) {
-
- System.out.println("flag="+flag);
- while(flag) {
- i++;
- if(i<=100) {
- progressBar1.setProgress(i);
- publishProgress(i);
- try {
- Thread.sleep(params[0]);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- } else {
- break;
- }
- }
- return "下载完毕";
- }
-
- @Override
- protected void onProgressUpdate(Integer... values) {
-
- textView1.setText(values[0]+"%");
- super.onProgressUpdate(values);
- }
-
- @Override
- protected void onPostExecute(String result) {
-
-
- setTitle(result);
- button1.setEnabled(true);
- super.onPostExecute(result);
- }
-
- }
-
- }
XML布局文件
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:padding="10dp" >
-
- <Button
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="开始"
- android:layout_gravity="center_horizontal" />
-
- <ProgressBar
- android:id="@+id/progressBar1"
- style="?android:attr/progressBarStyleHorizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- <TextView
- android:id="@+id/textView1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="TextView" />
-
- </LinearLayout>
效果图
点击开始,进度条即开始运行(同时按钮被禁用):
进度条加载完成后,按钮解禁,以供再次点击。