AsyncTask 是 Android提供的轻量级的异步类,可以直接继承 AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给 UI主线程。这个类的设计目的很明确,就是为了"执行一个较为耗时的异步任务(最多几秒钟),然后更新界面"。
这种需求本可以使用Handler 和 Thread 来实现,但是在单个后台异步处理时显得代码过多、结构过于复杂,因此 Android 提供了AsyncTask类。但是在使用多个后台异步操作并需要进行UI变更时,使用AsyncTask类就变得复杂起来,使用Handler 和 Thread则更加合适。
另外,这里所说的轻量级只是代码上的轻量级,而非性能上的,使用 AsyncTask 会更加消耗性能∶
AymcTask类有4个重要方法,这也是当一个异步任务被执行时要经历的4步,如表1-1 所示。
表1-1 AsyncTask类的4个重要方法
方法 | 作用 |
onPreExecute() | 在异步任务开始执行前在 UI线程中执行,一般用来设置任务参数 |
dolnBackground() | 最重要的方法,在子线程中执行(事实上,只有它在子线程中执行,其他方法都在UI线程中执行)。当onPreExecute()结束后,本方法立刻执行,用来进行后台的耗时计算,异步任务的参数会被传给它,执行完成的结果会被送给第四步。执行途中,它还可以调用 publishProgress()方法来通知 UI线程当前执行的进度 |
onProgressUpdate() | 当 publishProgress()被调用后,它在 UI线程中执行,刷新任务进度,一般用来刷新进度条等 UI部件 |
onPostExecute() | 当后台的异步任务完成后,它会在UI线程中被调用,并获取异步任务执行完成的结果 |
下面用一个实例来讲解如何使用 AsyncTask 类。创建一个继承自 AsyncTask 类的MyAsyncTask类,实现它的4个主要方法,并创建一个带参数的构造方法,用以介绍Activity类的Content 和布局管理器。在 dolnBackground()方法中模拟下载任务,并每隔1秒更新一次进度条。代码如下∶
package com.rfstar.asynctasktest;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MyAsyncTask extends AsyncTask {
private ProgressDialog progressDialog;
private ViewGroup viewGroup;
private Context context;
public MyAsyncTask(Context context,ViewGroup viewGroup)
{
this.viewGroup=viewGroup;
this.context=context;
}
@Override
protected void onPreExecute()
{
super.onPreExecute();
//使用一个进度条对话框;
progressDialog=new ProgressDialog(context);
progressDialog.setTitle("正在下载中,请稍后......");
//设置ProgressDialog样式为圆圈的形式
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.show();
}
@Override
protected String doInBackground(Object[] params)
{
//execute()方法传递的参数
String address=(String)params[0];
int flag=0;
while (flag<100){
flag+=20;
//跟新进度,将回调onProgressUpdate()方法
publishProgress(flag);
try{
Thread.sleep(1000);
}catch (Exception e){
}
}
return address+"从这个下载地址下载了一本小说,欢迎阅读。";
}
@Override
protected void onProgressUpdate(Object[] values){
super.onProgressUpdate(values);
//跟新进度条
progressDialog.setProgress((Integer)values[0]);
}
@Override
protected void onPostExecute(Object o){
super.onPostExecute(o);
//在布局中加入一个TextView
TextView textView=new TextView(context);
textView.setText((String)o);
viewGroup.addView(textView);
//关闭进度条
progressDialog.dismiss();
}
}
同时建立一个Activity,在布局文件中加入一个Button,当点击Button时,实例化MyAsyncTask类并调用excute()方法。布局文件代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/line"
tools:context=".MainActivity">
<Button
android:id="@+id/download_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="点击下载"/>
</LinearLayout>
MainActivity的代码如下:
package com.rfstar.asynctasktest;
import androidx.appcompat.app.AppCompatActivity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button downloadbutton;
private ProgressDialog progressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
downloadbutton=(Button)findViewById(R.id.download_btn);
downloadbutton.setOnClickListener(this);
}
@Override
public void onClick(View view) {
MyAsyncTask myAsyncTask=new MyAsyncTask(this,(LinearLayout)findViewById(R.id.line));
myAsyncTask.execute("小说下载地址:");
}
}
运行程序并点击“下载”按钮,将出现一个提示下载的进度条,如图1-1所示。
当完成下载之后,UI界面中会显示刚才模拟下载的文本,效果如图1-2所示。
图1-1点击下载并使用progressDialog来显示下载进度
图1-2将下载的内容传递到UI线程并显示
源码下载地址:链接:https://pan.baidu.com/s/1ExoSxaQRdjmwUUnDuSbUIQ 提取码:43ka