Android AsyncTask示例教程

时间:2020-02-23 14:28:45  来源:igfitidea点击:

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

Android AsyncTask

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类中使用的三种通用类型如下:

  • 参数:执行时发送给任务的参数类型
  • 进度:后台计算过程中发布的进度单位的类型
  • 结果:后台计算结果的类型

Android AsyncTask示例

要启动AsyncTask,MainActivity类中必须包含以下片段:

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

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

注意:

  • 必须在UI线程中创建并调用AsyncTask实例。

  • 永远不要调用在AsyncTask类中重写的方法。
    他们被自动称为

  • AsyncTask只能被调用一次。
    再次执行将引发异常

在本教程中,我们将实现一个AsyncTask,该过程将使进程在用户设置的给定时间内进入睡眠状态。

Android异步任务项目结构

Android 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="Sleep time in Seconds:"
  <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="Run Async task"
      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.theitroad.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("Sleeping..."); //Calls onProgressUpdate()
          try {
              int time = Integer.parseInt(params[0])*1000;

              Thread.sleep(time);
              resp = "Slept for " + params[0] + " seconds";
          } catch (InterruptedException e) {
              e.printStackTrace();
              resp = e.getMessage();
          } catch (Exception e) {
              e.printStackTrace();
              resp = e.getMessage();
          }
          return resp;
      }

      @Override
      protected void onPostExecute(String result) {
          //execution of result of Long time consuming operation
          progressDialog.dismiss();
          finalResult.setText(result);
      }

      @Override
      protected void onPreExecute() {
          progressDialog = ProgressDialog.show(MainActivity.this,
                  "ProgressDialog",
                  "Wait for "+time.getText().toString()+ " seconds");
      }

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

在上面的代码中,我们使用了AsyncTaskRunner类来执行AsyncTask操作。
以秒为单位的时间作为参数传递给类,并在给定的时间内显示ProgressDialog。