Android开发(5):多线程之AsyncTask

一、AsyncTask介绍

上一篇博客介绍了多线程handle的使用,但是handle需要通过post或sendMessage来使用handle通知主线程来更新UI,我们需要完成子线程和handle的内部实现,而AsyncTask封装了所有,我们只需要继承AsyncTask类,在类里面根据自己的需求重写相对应函数,需要在主线程执行的函数也在类里面重写,不需要我们重新在类外写函数接受信息,比起“Thread+handle”的组合简便了很多。

二、AsyncTask使用

1. 函数介绍

execute函数,子线程启动函数,子线程实例化后必须使用asynctask.execute()才可以启动子线程,可带参数

AsynaTask是个抽象类,我们使用时必须继承它,然后根据需要重写相关函数

(1)抽象类

public class MyAsyncTask extends AsyncTask<Params, Progress, Result >{}

三个参数为泛型类型,第一个参数为子线程启动时传入的参数,第二个参数为子线程处理过程中(还未结束,比如更新进度条)进行更新UI传递的参数,第三个参数是子线程处理完之后返回主线程的参数,如果不需要参数,只需要将其设为void。

(2)类中相关函数

  • doInBackground(Params[] params),子线程的处理操作,如果Result存在,比如第三个参数为String类型,则返回类型也为String,返回的数据将在下一个函数接收到。
  • onPostExecute(Result result),子线程结束后在主线程进行的操作,比如对UI进行更新,其中所带参数为doInBackground返回的类型。
  • onPreExecute(),子线程开始时的准备工作
  • onProgressUpdate(Progress[] progress),子线程执行过程中对UI的更新,比如即时更新进度条。参数为类中第二个参数。
  • onCancelled(),打断当前子线程,直接调用该函数,这样子线程就不会调用onPostExecute函数了。但该方法对IO操作无作用。
  • publishProgress(Progress progress),可以写在doInBackground函数中的一个方法,用于在子线程执行过程中将数据发送给onProgressUpdate,从而进行UI的更新。注意:该方法只能写在doInBackground。

(3)对象调用的方法

  • execute(Params[] params),实例化一个对象之后,调用该方法,启动子线程,可以传递数据。
  • executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, Params[] params),这也是对象调用的方法来启动子线程,这也可以传递数据,与上一条差别后面讲。
  • cancel(true),进而会调用onCancelled来结束当前子线程。

2. 类里面函数搭配

(1)最基本实用

doInBackground+onPostExecute,这两个函数是必须重写的,只实现简单的多线程操作就可以用这个搭配

(2)需要在子线程执行过程中更新UI

doInBackground+onPostExecute+onProgressUpdate+publishProgress(在doInBackground中使用)

(3)需要在子线程启动前做准备工作

[(2)|(1)] + onPreExecute

(4)可以手动停止子线程

[(2)|(1)|(3)]+onCancelled

3. 使用步骤

(1)继承AsyncTask类,并根据需求重写相对应函数

(2)实例化一个对象,可传递数据

(3)对象调用execute或者executeOnExecutor启动子线程

(4)如果需要,调用cancel(true)

三、串行与并行

  1. 一个对象只能execute一次,所以使用try+catch来防止出发两次。
  2. 一个AsyncTask的类的不同对象(无论是不是同一个类,只要继承类AsyncTask),默认情况(使用execute)是串行执行的,比如你同时对两个子线程对象调用execute,两个子线程并不会同时执行,而是串行方法。
  3. 如何并行:使用executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,Params[] params)来启动子线程,这时候子线程(不同对象)就是并行的。
  4. 并行串行选择:并行执行可以不用等上一个AsyncTask对象执行完就可以执行,但如果对同一个UI进行更新,会造成混乱。

四、AsyncTask内存泄露

和上一篇一样,这里不多讲

  1. 将AsyncTask类声明为static内部类
  2. 手动将子线程全部移除
  3. 在destory使用cancel(boolean),会打断当前子线程,这样就不会调用onPostExecute,而是调用onCanclled。对IO操作不起作用。

猜你喜欢

转载自blog.csdn.net/chenxz_/article/details/84444936
今日推荐