AsyncTask异步任务的基本使用和注意事项

AsyncTask异步任务的基本使用和注意事项

Android小彩虹2021-08-25 23:33:46220A+A-

一、概述

AsyncTask是一种轻量级的异步任务类,属于抽象类,使用时需实现子类和相关方法。它可以在线程池中执行后台任务,然后把执行的进度和最终结果传递给主线程并在主线程中更新UI,通过AsyncTask可以更加方便执行后台任务以及在主线程中操作UI,可以轻松解决多线程之间的通信问题,但是AsyncTask并不适合进行特别耗时的后台任务,对于特别耗时的任务来说,建议使用线程池。

二、作用

  1. 实现多线程:在工作线程中执行任务,如耗时任务。

  2. 异步通信、消息传递:实现工作线程&主线程(UI线程)之间的通信,即:将工作线程的执行结果传递给主线程,从而在主线程中执行相关的UI操作,最终保证线程安全。

三、优点

  1. 方便实现异步通信:不需使用 “任务线程(如继承Thread类)+ Handler”的复杂组合。

  2. 节省资源:采用线程池的缓存线程 + 复用线程,避免了频繁创建&销毁线程所带来的系统资源开销。

四、核心方法

要掌握AsyncTask,就要掌握三个参数和四个步骤。

1、三个参数

AsyncTask<Params, Progress, Result>

Params:表示异步任务执行时的参数类型,该参数会传给AysncTask的doInBackground()方法

Progress:表示异步任务的执行进度的参数类型,该参数会作为onProgressUpdate()方法的参数

Result:表示异步任务的返回结果的参数类型,该参数会作为onPostExecute()方法的参数

在定义一个类继承AsyncTask类的时候,必须指定好这三个泛型的类型,如果都不指定的话,则都将其写成Void,例如:

AsyncTask <Void, Void, Void>

2、四个步骤

当执行一个异步任务时,需要按照下面的4个步骤分别执行:

onPreExecute():这个方法是在执行异步任务之前的时候执行,并且是在UI Thread当中执行的, 通常我们在这个方法里做一些UI控件的初始化的操作,例如弹出ProgressDialog。

doInBackground(Params...params):在onPreExecute()方法执行完后,会马上执行这个方法,这个方法就是来处理异步任务的方法,Android操作系统会在后台的线程池当中开启一个worker thread来执行 这个方法(即在worker thread当中执行),执行完后将执行结果发送给最后一个onPostExecute方法,在这个方法里,我们可以从网络当中获取数据等一些耗时的操作。

onProgressUpdate(Progess...values):这个方法也是在UIThread当中执行的,在异步任务执行的时候,有时需要将执行的进度返回给UI界面,例如下载一张网络图片,我们需要时刻显示其下载的进度,就可以使用这个方法来更新进度。这个方法在调用之前,我们需要在doInBackground方法中调用一个 publishProgress(Progress) 的方法来将进度时时刻刻传递给onProgressUpdate方法来更新。

onPostExecute(Result...result):当异步任务执行完之后,就会将结果返回给这个方法,这个方法也是在UI Thread当中调用的,我们可以将返回的结果显示在UI控件上。

3、额外补充doInBackground和onCancelled

(1)为什么AsyncTask抽象类只有一个doInBackground的抽象方法呢?

如果要做一个异步任务,我们必须要为其开辟一个新的Thread,让其完成一些操作,而在完成这个异步任务时,可能并不需要弹出ProgressDialog,并不需要随时更新ProgressDialog的进度条,也并不需要将结果更新给UI界面,所以除了doInBackground方法之外的三个方法,都不是必须有的,因此必须要实现的方法是doInBackground方法。

(2)Cancel a Task-取消异步任务

onCancelled()在异步任务被取消时回调,可以在任何时刻来取消异步任务的执行,通过调用cancel(boolean)方法,调用完这个方法后系统会随后调用isCancelled()方法并且返回true。如果调用了这个方法,那么在doInBackgroud()方法执行完之后,就不会调用onPostExecute()方法了,取而代之的是调用onCancelled()方法。如果有必要的话,为了确保Task已经被取消了,需要经常调用isCancelled()方法来判断。

五、基本使用

AsyncTask的使用步骤分为两步:

  • 第一步:创建AsyncTask子类 & 根据需求实现核心方法
  • 第二步:创建AsyncTask子类的实例对象,手动调用execute()执行异步线程任务
第一步:创建AsyncTask子类
    1、继承AsyncTask类
    2、为3个泛型参数指定类型;若不使用,可用java.lang.Void类型代替
    3、根据需求,在AsyncTask子类内实现核心方法

  private class MyTask extends AsyncTask<Params, Progress, Result> {
  
     //执行线程任务前的操作
      @Override
      protected void onPreExecute() {
           ...
        }

      //接收输入参数、执行任务中的耗时操作、返回线程任务执行的结果
      @Override
      protected String doInBackground(String... params) {
            //自定义的线程任务
            HttpClient httpClient = new DefaultHttpClient() ;
            ....
            
            //可调用publishProgress()显示进度, 之后将执行onProgressUpdate()
             publishProgress(count);
         }

      //在主线程 显示线程任务执行的进度
      @Override
      protected void onProgressUpdate(Integer... progresses) {
            ...
        }

      //接收线程任务执行结果、将执行结果显示到UI组件
      @Override
      protected void onPostExecute(String result) {
             // UI操作
             .....
        }

      //将异步任务设置为:取消状态
      @Override
        protected void onCancelled() {
             ...
        }
  }

第二步:创建AsyncTask子类的实例对象,手动调用execute(Params... params) 从而执行异步线程任务
 MyTask mTask = new MyTask();
 mTask.execute();
 

六、使用时注意事项

1、使用AsyncTask遵循的原则

(1)AsyncTask子类的实例必须在UI线程中创建

(2)execute方法必须在UI线程中调用

(3)同一个AsyncTask实例对象只能执行1次,若执行第2次将会抛出异常

(4)执行任务中,系统会自动调用AsyncTask的一系列方法:onPreExecute()、doInBackground()、onProgressUpdate() 、 onPostExecute() 不能手动调用这些方法

2、AsyncTask引起的内存泄漏

原因:非静态内部类持有外部类的匿名引用,导致Activity无法释放

解决: AsyncTask内部持有外部Activity的弱引用 & AsyncTask改为静态内部类 & 在Activity销毁之前,AsyncTask.cancel()取消运行,以此来保证程序的稳定

七、总结

本文介绍了AysncTask的基本使用和使用过程中注意事项,包括遵守原则和内存泄漏。稍后会分析AysncTask的工作原理,包括多任务时AysncTask采用的是串行or并行以及源码分析。

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示 | 支付宝红包
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1
本网站由 提供CDN/云存储服务

联系我们