Android学习——AsyncTask

本文详细介绍了Android中的AsyncTask类,包括其定义、执行流程、泛型参数及常用方法。通过实例展示了如何使用AsyncTask进行倒计时和进度条更新,对比了AsyncTask与Handler的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是AsyncTask

定义:处理异步消息的一个异步类
含义 :为一个轻量级的异步类,与Handler作用相似,不同的是不需要建造子线程主线程

Handler的调用过程:

1. UI线程创建Handler
2. 启动子线程,执行耗时操作
3. 向主线程发送消息
4. handlerMessage接收消息

AsyncTask的执行过程:

1. 新建UI线程,启动AsyncTask
2. 执行耗时消息
3. 接收消息

AsyncTask的泛型参数和常用方法:

 - Params:启动任务执行的输入参数
 - Progress:后台任务执行的百分比
 - Result:后台执行任务最终返回的结果

AsyncTask的常用方法:

  • onPreExecute方法:运行在主线程中,最先调用此方法
  • doInBackgroud:执行完运行在子线程中,执行耗时操作
  • onProgeessUpate方法:显示当前进度,运行在主线程中,需使用publishProgress
  • publishProgress:用于触发onProgeessUpate
  • onPostExecute:当异步任务执行完成后,调用此方法,运行在主线程中

  • execute:启动异步任务,必须在UI线程中调用,按照先后顺序执行多个

  • executeOnExecutor:启动异步任务,必须在UI线程中调用,并行任务同时执行多个任务,最多只能并行5个

如何使用AsyncTask

使用AsyncTask步骤:

1. 新建内部类继承AsyncTask
2. 定义AsyncTask的三种泛型参数
3. 重写doInBackground抽象方法
4. 重写onPreExecute/onProgressUpdate/onPostExecute方法
5. 在需要启动的地方调用execute方法

不带进度的AsyncTask方法的调用顺序:

1. 定义AsyncTask   String、int
2. 在UI线程中启动AsyncTask
3. 可初始化控件
4. 执行耗时操作
5. 根据Result设置控件

带进度的AsyncTask的调用顺序:

1. 定义AsyncTask
2. 在UI线程中启动AsyncTask
3. 可初始化
4. 执行耗时操作

使用ASyncTask做倒计时(附代码)

附视图代码

 <EditText
        android:id="@+id/time_et"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/time_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/daojishi_btn"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="带进度AsyncTask倒计时"/>

步骤:

 1. 绑定ID, 监听按钮
 2. 创建一个类继承AsyncTask,写三个类型方法,实现方法  //耗时操作执行前,对UI的更改
 3. onPreExecute方法(主线程),更新时间  //耗时操作执行前,调用此方法,可初始化控件,可省略
 4. doInBackgroud方法(子线程),设置倒计时循环,返回计时结束//执行耗时操作
 5. onProgressUpdate方法(主线程),显示更新时间//更新当前进度
 5.  onPostExecute方法(主线程),返回更新按钮//耗时操作执行完成后,调用此方法

代码演示

public class MainActivity extends AppCompatActivity {
    private EditText timeet;
    private TextView timetv;
    private Button daojishibtn;


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

        bindID();

        daojishibtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int time=Integer.parseInt(timeet.getText().toString());//把int类型转换成String类型
                new MyTask().execute(time);//修改文字框内容
            }
        });
    }

    private void bindID() {
        timeet=findViewById(R.id.time_et);
        timetv=findViewById(R.id.time_tv);
        daojishibtn=findViewById(R.id.daojishi_btn);
    }


    class MyTask extends AsyncTask<Integer,Integer,String>{

    //倒计时循环
        @Override
        protected String doInBackground(Integer... Integer) {
            for(int i=Integer[0];i>0;i--){
                try{
                    Thread.sleep(1000);
                    publishProgress(i);//调用onProgressUpdate方法
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return "计时结束";
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            timetv.setText("倒计时:"+values[0]);
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            daojishibtn.setText(s);//结果回传更新
        }
    }
}

使用AsyncTask做进度条(附代码)

附视图代码

 <ProgressBar
        android:id="@+id/pb1"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100" />
    <ProgressBar
        android:id="@+id/pb2"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100" />

    <Button
        android:id="@+id/btn1"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="开始下载"/>
    <Button
        android:id="@+id/btn2"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="开始下载"/>

步骤:

 1. 绑定ID,监听按钮,设置进度条最大值
 2. 使用switch语句,选择判断按下了哪个按钮
 3. 创建MyTask方法继承ASyncTask,写三个类型方法
 4. doInBackground方法,使用for方法进行进度更新,定义一个任意数,返回任意数
 5. onProgressUpdae方法,定义两个进度条更新
 6. onPostExecute方法,使用swtich方法定义选择对应的按钮更新“下载完成”

代码演示:

public class Jindutiao extends AppCompatActivity implements View.OnClickListener{
    private Button btn1;
    private Button btn2;
    private ProgressBar pb1;
    private ProgressBar pb2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_jindutiao);

        bindID();

    }

    private void bindID() {
        btn1=findViewById(R.id.btn1);
        btn2=findViewById(R.id.btn2);
        pb1=findViewById(R.id.pb1);
        pb2=findViewById(R.id.pb2);

        btn1.setOnClickListener(this);
        btn2.setOnClickListener(this);

        pb1.setMax(10);//设置最大值
        pb2.setMax(10);//设置最大值
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn1:
                btn1.setEnabled(false);
                btn1.setText("正在下载");
                new MyTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,1);//改成并行
                break;
            case R.id.btn2:
                btn2.setEnabled(false);
                btn2.setText("正在下载");
                new MyTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,2);//改成并行
                break;
        }
    }

    class MyTask extends AsyncTask<Integer,Integer,Integer>{
        @Override
        protected Integer doInBackground(Integer... integers) {

            int whichpb=integers[0];//定义一个任意数

            for(int i=1;i<=10;i++){
                try {
                    Thread.sleep(1000);
                    publishProgress(i,whichpb);//添加任意数
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return whichpb;//返回至任意一个数
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);

            //定义两个进度条进行
            switch (values[1]){
                case 1:
                    pb1.setProgress(values[0]);
                    break;
                case 2:
                    pb2.setProgress(values[0]);
                    break;
            }
        }
        @Override
        protected void onPostExecute(Integer integer) {
            super.onPostExecute(integer);

            //定义选择两个下载按钮
            switch (integer){
                case 1:
                    btn1.setText("下载完成");
                    btn1.setEnabled(true);
                    break;
                case 2:
                    btn2.setText("下载完成");
                    btn2.setEnabled(true);
                    break;
            }
        }
    }
}

Execute()和executeOnExecutor有何区别

  • execute:启动异步任务,必须在UI线程中调用,按照先后顺序执行多个
  • executeOnExecutor:启动异步任务,必须在UI线程中调用,并行任务同时执行多个任务,最多只能并行5个

一般execute运行后想要修改成executeOnExecutor,直接在监听判断按钮时,新建的方法改为executeOnExecutor运行

public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn1:
                btn1.setEnabled(false);
                btn1.setText("正在下载");
                new MyTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,1);//改成并行
                break;
            case R.id.btn2:
                btn2.setEnabled(false);
                btn2.setText("正在下载");
                new MyTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,2);//改成并行
                break;
        }
    }

更喜欢ASyncTask还是更喜欢Handler,为什么?

相对于我本人而言,我个人更喜欢ASyncTask

  • 首先秉着后来者居上的一个微妙想法,Handler我在大一的时候就已经接触了,当时就对此留下了一定的印象,等到现在接触AsyncTask就相对惊艳了
  • 其次Handler每次都需要启动子线程发送消息,handlerMessage接收消息,相对于ASyncTask不需要定义子线程主线程,显得尤其累赘
  • 最后虽然AsyncTask每次都需要重复的定义三四个方法,但是只是一个形式,不同的视图使用的都是不同的方法代码,显得尤其的思路清晰,逻辑分明
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值