AsyncTask的初识
一.什么是AsyncTask
AsyncTask是一个轻量级的异步任务类,它可以在线程池中执行后台任务,然后把执行的进度和结果传递给主线程并在主线程中更新UI
AsyncTask这个类的声明如下:
public abstract class AsyncTask<Params, Progress, Result>
它提供了 Params,Progress 和Result 三个泛型参数,在下面会仔细分析这三个泛型参数的具体含义。
AsyncTask提供了四个核心方法:
- onPreExecute()
此方法在主线程中执行,在异步任务执行之前,此方法会被调用,一般用于一些准备工作,例如下载进度条的初始化。 - doInBackground(Params… params)
此方法在子线程中执行,用于执行异步任务,注意这里的params就是AsyncTask的第一个参数类型。
注意:在此方法中可以通过调用publicProgress方法来更新任务进度,publicProgress会调用 onProgressUpdate 方法。 - onProgressUpdate(Progress… values)
此方法在主线程中执行,values的类型就是AsyncTask传入的第二个参数类型,当后台任务的执行进度发生变化时此方法执行。
注意:此方法必须由publicProgress,激发才可调用 - onPostExecute(Result result)
此方法在主线程中执行,在 doInBackground 方法执行完成以后此方法会被调用,其中result的类型就是AsyncTask传入的第三个参数类型,它的值就是doInBackground方法的返回值。
二.AsyncTask的用法
1.新建一个内部类继承AsyncTask
2.定义AsyncTask的三种泛型参数(什么是泛型参数?第三小节具体分析)
3.重写doInBackground抽象方法(必须重写该方法)
4.根据需求重写其他onPostExecute ,onProgressUpdate , onPreExecute
三.长度可变的参数列表和泛型参数列表
1.长度可变的参数列表
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
tv_one.setText(values[0]);
}
- 类型后面三个点(String…),是从Java 5开始,Java语言对方法参数支持一种新写法,叫可变长度参数列表,其语法就是类型后跟…,表示此处接受的参数为0到多个Object类型的对象,或者是一个Object[]。 例如我们有一个方法叫做test(String…strings),那么你还可以写方法test(),但你不能写test(String[] strings),这样会出编译错误,系统提示出现重复的方法。
- 在使用的时候,对于test(String…strings),你可以直接用test()去调用,标示没有参数,也可以用去test(“aaa”),也可以用test(new String[]{“aaa”,”bbb”})。
- 另外如果既有test(String…strings)函数,又有test()函数,我们在调用test()时,会优先使用test()函数。只有当没有test()函数式,我们调用test(),程序才会走test(String…strings)。
2.泛型参数列表
package generics;
//可变参数列表
public class Test2 {
public static void print(String str,Object... obj) {
System.out.println("str="+str);
for (int i = 0; i < obj.length; i++) {
System.out.println(obj[i]);
}
}
public static void main(String[] args) {
print("phl",1,2,"multiple parameters",true,3.2134);
}
}
在这个例子中,我们感到奇怪的地方有如下几点:
public static void print(String str,Object… obj);
这里的参数Object…obj是什么意思呢?代表的就是可变参数列表,“…”是可变参数列表的特殊标志。意思就是只要是属于Object类都可以作为参数传递进来。我们都知道,在Java中,所有的类都是直接或者间接继承自Object类。所以我们可以这么写代码print(“phl”,1,2,”multiple parameters”,true,3.2134); Integer,String,Boolean,Float,均可以作为参数使用。
四.使用AsyncTask 案例——倒计时
MainActivity
package com.example.a22120.day4_asynctask;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
public TextView tv_one;
private Button btn_one;
private int cont=10;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindId();
}
private void bindId() {
tv_one=findViewById(R.id.tv_top);
btn_one=findViewById(R.id.btn_one);
btn_one.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn_one:
new DownTask().execute();
break;
default:
break;
}
}
class DownTask extends AsyncTask<String ,String,String>{
@Override
protected void onPreExecute() {
super.onPreExecute();
tv_one.setText("正在下载");
}
//onProgressUpdate必须要又 publishProgress(cont+"");进行激发才会调用
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
tv_one.setText(values[0]);
}
@Override
protected String doInBackground(String... strings) {
while (cont>=0){
publishProgress(cont+"");
cont--;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "下载完成";
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
tv_one.setText(s);
}
}
}
布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.a22120.day4_asynctask.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:text="未开始"
android:id="@+id/tv_top"
android:gravity="center"
android:textSize="40dp"
android:layout_gravity="center"
/>
<Button
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="@+id/btn_one"
android:text="开始"
android:gravity="center"
android:textSize="30dp"
/>
</LinearLayout>
五.使用AsyncTask完成多个异步任务
现在我们了解了如何使用AsyncTas完成异步任务,其实原理和Handler是有很多相似之处对的,但是相比之下AsyncTask是会简易很多。
这节我们看看AsyncTask是如何完成多个异步任务的处理的: