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

android代替worker的方案_异步任务

2.定义AsyncTask的三种泛型参数(什么是泛型参数?第三小节具体分析)

3.重写doInBackground抽象方法(必须重写该方法)

android代替worker的方案_泛型_02

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 案例——倒计时

android代替worker的方案_泛型_03


android代替worker的方案_android_04

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是如何完成多个异步任务的处理的:

android代替worker的方案_泛型_05


android代替worker的方案_泛型_06