Android进阶——AsyncTask

本文详细介绍了Android中的AsyncTask,包括其概念、优点、使用步骤和案例,以及execute和executeOnExecutor的区别。AsyncTask简化了异步任务处理,减少了开发者对Looper、MessageQueue、Handler的依赖,提供了一种轻量级的线程处理方式。

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

Android的线程状态——AsyncTask

前言:在上一章节,我们学习了什么是Handler,以及涉及到的关键词UI线程和子线程。这一章节,我们将去学习什么AsyncTsak,也会知道AsyncTsak与Handler有异曲同工之妙。


(一)什么是AsyncTask

概念:

我们知道Handler是一种Android中一种处理异步消息的核心类,而 AsyncTask其实也可以这么定义。但是我们知道使用Handler时,我们需要自己去创建子线程,但是AsyncTask则不需要。这并不代表它就用不到子线程,而是AsyncTask在执行耗时操作时,系统会帮助启动子线程。所以AsyncTask被称为轻量级(实现代码量少)的异步类。


(二)AsyncTask的优点:

  1. 代码量少;
  2. 减低开发者的开发难度;
  3. 直接继承于Objict类;
  4. 可以忽略Looper、MessagQueue、Handler等复杂对象,实现更便捷地完成异步耗时操作。

(三)如何使用AsyncTask

这里写图片描述

步骤:

通过上面这张图,我们可以看到它告诉我们需要重写几个方法,但是也省略掉一些步骤,下面我就总结一下AsyncTask的使用步骤。

  1. 新建内部类继承AsyncTask;
  2. 定义AsyncTask的三种泛型参数(所谓泛型参数,其实就是任何类型的参数啦);
  3. 重写doInBackground()抽象方法,而我们需要做的耗时操作就是在这里面执行的。记住,此方法在AsyncTask中是必有的;(运行在子线程中)
  4. 重写onRreExecute()方法和onPostExecute()方法,这里可以根据需要来决定是否用它们;(皆运行在UI线程中)
  5. 当需要AsyncTask带进度时,则需要用到onProgressUpdate()方法。在此之前,我们需要用到publishProgress方法来触发onProgerssUpdate()方法,而publishProgerss方法则是在doInBackground()方法中使用,也可以参考上面图片进行理解;
  6. 最后在需要启动的地方调用execute方法或executeOnexecutor方法,后面我们会讲到这两者之间的差别。

(四)AsyncTask使用案例

1)不带进度

题目:点击Button按钮进行下载,TextView中的内容由“开始下载”变为正在下载,下载时间为5秒,下载完成后变为“完成下载”。

效果展示:

这里写图片描述

代码演示:

  • 为Button添加监听;
 button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
  • 新建内部类继承AsyncTask;
 class MyProgress extends AsyncTask<String,Integer,String>{
  • 重写doInBackground方法,执行耗时操作;
 @Override
        protected String doInBackground(String... strings) {
            for (int i=0;i<5;i++){
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return  "完成下载";
        }
  • 获得return传到onPostExecute方法中的返回值;
    这里写图片描述
  • 在需要启动的地方调用execute方法。
new MyProgress().execute();
2)带进度

题目:在EditText中输入一个数,点击Button按钮进行倒计时。

效果展示:

这里写图片描述

代码演示:

 jishiBTN.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int time=Integer.parseInt(jishiET.getText().toString());
                new JishiProgress().execute(time);

            }
        });
 class JishiProgress extends AsyncTask<Integer,Integer,String>{


        @Override
        protected String doInBackground(Integer... integers) {
            for(int i=integers[0];i>0;i--){
                try {
                    Thread.sleep(1000);
                    publishProgress(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            return "计时结束";
        }

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

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            jishiTV.setText(s);
        }

    }

题目:点击按钮,按钮修改为正在下载且在下载时不能点击按钮,使用进度条显示进度,下载完成后按钮修改为下载完成。

效果展示:
这里写图片描述
代码演示:
1.XML行布局创建progressBar和Button控件,并设置progressBar为水平进度条;

style="@style/Widget.AppCompat.ProgressBar.Horizontal"

2.Acitivity

public class JinduActivity extends AppCompatActivity implements View.OnClickListener{

    private ProgressBar jinduPB;
    private Button jinduBTN1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_jindu);

        bindID();


    }

    private void bindID() {
        jinduPB=findViewById(R.id.jindu_pb);
        jinduBTN1=findViewById(R.id.jindu_btn);

        jinduPB.setMax(10);
        jinduBTN1.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.jindu_btn:
                jinduBTN1.setEnabled(false);
               new JinduProgress().execute();
              break;


        }
    }

    class JinduProgress extends AsyncTask<Integer,Integer,Integer>{

        @Override
        protected Integer doInBackground(Integer... integers) {
            for(int i=0;i<=10;i++){
                try {
                    Thread.sleep(1000);
                    publishProgress(i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return 1;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            jinduPB.setProgress(values[0]);

        }

        @Override
        protected void onPostExecute(Integer integer) {
            super.onPostExecute(integer);
            jinduBTN1.setText("下载完成");
            jinduBTN1.setEnabled(true);
        }
    }
}

题目:在上一题的基础上,实现两个进度条的并行加载。

效果展示:

这里写图片描述
代码演示:

public class TwoJDActivity extends AppCompatActivity implements View.OnClickListener {

    private ProgressBar bar1;
    private ProgressBar bar2;
    private Button btn1;
    private Button btn2;


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

        bindID();
    }

    private void bindID() {
        bar1 = findViewById(R.id.two_bar1);
        bar2 = findViewById(R.id.two_bar2);
        btn1 = findViewById(R.id.two_btn1);
        btn2 = findViewById(R.id.two_btn2);

        bar1.setMax(10);
        bar2.setMax(10);

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

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

    }

    class TwoProess extends AsyncTask<Integer,Integer,Integer>{


        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @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:
                    bar1.setProgress(values[0]);
                      break;
                case 2:
                    bar2.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和excuteOnExcutor的区别

其实这两者之间的区别很容易记住,excute使进度条串行,即一个进度条下载完成之后,第二条进度条才开始下载。而excuteOncutor则可以使几个进度条同时运行。


(六)倾向于Handler还是AsyncTask?

我个人更喜欢用AsyncTask,原因很简单,代码少,更快捷。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值