美文网首页Android
多线程—AsyncTask

多线程—AsyncTask

作者: 似焰如火 | 来源:发表于2019-12-28 16:47 被阅读0次

    1 说在头里

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

    • Handler 实现:
    • Activity.runOnUiThread(Runnable):
    • View.post(Runnable):
    • View.postDelayed(Runnable, long):

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

    2 正题

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

    • 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>
    

    相关文章

      网友评论

        本文标题:多线程—AsyncTask

        本文链接:https://www.haomeiwen.com/subject/dgcdoctx.html