Android

多线程—AsyncTask

2019-12-28  本文已影响0人  似焰如火

1 说在头里

开始之前,还是要先逼逼几句。都知道,Android中子线程是不能直接更新UI的,如果想要修改,Android提供了以下集中方式:

对于异步任务,安卓提供更更为轻量级的操作方式,那就是今天的主角AsyncTask。这位哥哥是一个抽象类,需要继承,并且在继承时,需要指定3个泛型参数。

2 正题

AsyncTask适用于简单的异步任务,无需借助线程和Handler实现。首先说一下AsyncTask<Params, Progress, Result>三个泛型参数含义:

看不懂说啥呢?没关系,先放着,待会回头看。要使用这个类很简单,废话没有,三步走。

  1. 创建AsyncTask的子类,并为三个泛型参数指定类型,如果不需要使用,直接给个Void(Void是大写V,小写v会报错)
  2. 根据任务需求,重写AsyncTask的一些方法,有几个方法需要说明一下:
  • doInBackground(Params...): 该方法应该被重新,该方法就是后台要执行的任务。在该方法中可以直接调用publishProgress(Progress... Values)更新任务的执行进度。
  • onProgressUpdate(Progress... Values): 该方法在publishProgress(Progress... Values)被调用后被触发执行。
  • onPreExecute(): 一般该方法在执行后台任务前被调用,用于完成一些初始化操作,比如UI显示下载进度条。
  • onPostExecute(Result result): doInBackground()方法执行完成后,系统会回调该方法,doInBackground()的返回值是该方法的输入参数。
  1. 在UI线程中创建一个AsyncTask对象,并调用execute()方法。注意,每个AsyncTask只能执行一次,多次执行会抛出异常。

3 举个栗子

使用AsyncTask做一个倒计时,很简单按照上面三步走原则进行实践。

import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;


public class MainActivity extends AppCompatActivity {
    private TextView show;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        show = findViewById(R.id.show);

    }

    public void start(View source) {
        //第三步在UI线程中创建一个AsyncTask对象,并调用execute()方法
        TimerTask task = new TimerTask(this);
        task.execute(new Integer(10));

    }
    //第一步创建一个AsyncTask的子类
    class TimerTask extends AsyncTask<Integer, Integer, Void> {
        Context mContext;
        public TimerTask(Context ctx) {
            mContext = ctx;
        }
        //第二步,实现doInBackground方法,onProgressUpdate方法
        @Override
        protected Void doInBackground(Integer... params){
            int num = params[0].intValue();
            while(num > 0){
                num--;
                publishProgress(new Integer(num));
                try {
                Thread.sleep(1000);} catch (InterruptedException err) {}
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... num) {
            int i = num[0].intValue();
            if (i >= 0) {
                show.setText(num[0].intValue()+" ");
            } else {

            }
        }
    }
}

4 最好有个总结

在使用AsyncTask时,要指定这三个泛型参数,三种泛型类型分别代表“启动任务执行的输入参数”、“后台任务执行的进度”、“后台计算结果的类型”。
一个异步任务的执行一般包括以下几个步骤:
1.execute(Params… params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。
2.onPreExecute(),在execute(Params… params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。
3.doInBackground(Params… params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress… values)来更新进度信息。
4.onProgressUpdate(Progress… values),在调用publishProgress(Progress… values)时,此方法被执行,直接将进度信息更新到UI组件上。
5.onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。

上面五种方法中的参数要与上面自己指定的泛型类型要保持一致。

此部分内容属于转载,转载信息如下
————————————————
版权声明:本文为CSDN博主「csd54496」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/csd54496/article/details/45848405

顺便给一下xml文件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="138dp"
        android:layout_marginTop="198dp"
        android:layout_marginEnd="160dp"
        android:layout_marginBottom="78dp"
        android:text="10"
        android:textSize="100dp"
        app:layout_constraintBottom_toTopOf="@+id/button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <Button
        android:id="@+id/button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="57dp"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="293dp"
        android:onClick="start"
        android:text="开始"
        android:visibility="visible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/show"
        tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
上一篇下一篇

猜你喜欢

热点阅读