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示例项目