Android异步任务(AsyncTask)完整开发教程:从入门到精通的实例详解

这是文章《Android AsyncTask示例教程》的第1部分(共1部分)。

今天我们要研究Android AsyncTask。我们将开发一个Android示例应用程序,在后台执行一个抽象的AsyncTask。

Android 异步任务

Android AsyncTask是由Android提供的一个抽象类,它使我们可以在后台执行重任务,同时保持UI线程的轻量化,从而使应用程序更加响应。Android应用在启动时只运行在一个线程上。由于这种单线程模型,执行需要较长时间来获取响应的任务可能会使应用程序无法响应。为了避免这种情况,我们使用android AsyncTask在专用线程上执行重任务,并将结果传递回UI线程。因此,在Android应用中使用AsyncTask始终使UI线程保持响应。下面定义了在android AsyncTask类中使用的基本方法:

  • doInBackground() : 此方法包含需要在后台执行的代码。在这个方法中,我们可以通过publishProgress()方法多次发送结果到UI线程。要通知后台处理已完成,我们只需要使用return语句。
  • onPreExecute() : 此方法包含在后台处理开始前执行的代码。
  • onPostExecute() : 此方法在doInBackground方法完成处理后调用。doInBackground的结果将传递给此方法。
  • onProgressUpdate() : 此方法接收来自doInBackground方法的进度更新,该更新通过publishProgress方法发布,并且此方法可以使用此进度更新来更新UI线程。

在Android的AsyncTask类中,有以下三种通用类型。

  • Params : 执行任务时发送给任务的参数类型。
  • Progress : 后台计算期间发布的进度单元类型。
  • Result : 后台计算结果的类型。

安卓AsyncTask示例

要启动一个AsyncTask,在MainActivity类中必须包含以下代码段:

MyTask myTask = new MyTask();
myTask.execute();

在上面的代码片段中,我们使用了一个扩展了AsyncTask类的示例类名,并使用execute方法来启动后台线程。注意:

  • AsyncTask实例必须在UI线程中创建和调用。
  • AsyncTask类中被覆盖的方法不应该被手动调用。它们会被自动调用。
  • AsyncTask只能被调用一次。再次执行它将抛出异常。

在这个教程中,我们将实现一个AsyncTask,它能让进程根据用户设置的时间段进入睡眠状态。

安卓异步任务项目结构

安卓异步任务示例代码

xml布局在activity_main.xml中定义,如下所示:activity_main.xml

<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/tv_time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="10pt"
        android:textColor="#444444"
        android:layout_alignParentLeft="true"
        android:layout_marginRight="9dip"
        android:layout_marginTop="20dip"
        android:layout_marginLeft="10dip"
        android:text="睡眠时间(秒):"/>
    <EditText
        android:id="@+id/in_time"
        android:layout_width="150dip"
        android:layout_height="wrap_content"
        android:background="@android:drawable/editbox_background"
        android:layout_toRightOf="@id/tv_time"
        android:layout_alignTop="@id/tv_time"
        android:inputType="number"
        />
    <Button
        android:id="@+id/btn_run"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="运行异步任务"
        android:layout_below="@+id/in_time"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="64dp" />
    <TextView
        android:id="@+id/tv_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="7pt"
        android:layout_below="@+id/btn_run"
        android:layout_centerHorizontal="true" />
</RelativeLayout>

在上述布局中,我们使用了预定义的可绘制对象作为EditText的边框。下面是MainActivity.java的定义。

package com.Olivia.asynctask;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private Button button;
    private EditText time;
    private TextView finalResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        time = (EditText) findViewById(R.id.in_time);
        button = (Button) findViewById(R.id.btn_run);
        finalResult = (TextView) findViewById(R.id.tv_result);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AsyncTaskRunner runner = new AsyncTaskRunner();
                String sleepTime = time.getText().toString();
                runner.execute(sleepTime);
            }
        });
    }

    private class AsyncTaskRunner extends AsyncTask<String, String, String> {

        private String resp;
        ProgressDialog progressDialog;

        @Override
        protected String doInBackground(String... params) {
            publishProgress("正在休眠..."); // 调用onProgressUpdate()
            try {
                int time = Integer.parseInt(params[0])*1000;

                Thread.sleep(time);
                resp = "休眠了 " + params[0] + " 秒";
            } catch (InterruptedException e) {
                e.printStackTrace();
                resp = e.getMessage();
            } catch (Exception e) {
                e.printStackTrace();
                resp = e.getMessage();
            }
            return resp;
        }


        @Override
        protected void onPostExecute(String result) {
            // 长时间操作的结果执行
            progressDialog.dismiss();
            finalResult.setText(result);
        }


        @Override
        protected void onPreExecute() {
            progressDialog = ProgressDialog.show(MainActivity.this,
                    "进度对话框",
                    "请等待 "+time.getText().toString()+" 秒");
        }


        @Override
        protected void onProgressUpdate(String... text) {
            finalResult.setText(text[0]);
            
        }
    }
}

在以上代码中,我们使用AsyncTaskRunner类来执行AsyncTask操作。以秒为单位的时间作为参数传递给该类,并且对于给定的时间量显示一个ProgressDialog。下面的图片是项目生成的输出,用户设定的时间为5秒。这就结束了本教程。您可以从下面的链接下载最终的Android AsyncTask项目。

下载Android AsyncTask示例项目

bannerAds