AsyncTask的弊端

Android开发中,AsyncTask可以替代Handler和Thread来处理后台操作和通知Ui刷新,适用于处理异步数据,并将更新Ui的场景,AsyncTask适用于后台操作只有几秒的短时操作。但是AsyncTask本身存在很多糟糕的问题,如果使用中不注意,将会影响程序的健壮性。

AsyncTask和Handler对比

注意:按照Android官方文档支出,AsyncTask被推荐为处理短时间(10秒以内)的操作,即本地的轻量IO操作.不适合使用网络这样时间不定的操作.

共同点

都是为了解决耗时操作的问题,主要区别在于一个流程完善,拿来就用(AsyncTask),一个偏向自主定制,扩展性高(Handler+Thread)。

  • AsyncTask比Handler轻量级,对吗?
  1. 通过看源码,发现AsyncTask实际上就是一个线程池,而网上的说法是AsyncTask比handler要轻量级,显然上不准确的,只能这样说,AsyncTask在代码上比handler要轻量级别,而实际上要比handler更耗资源,因为AsyncTask底层是一个线程池!而Handler仅仅就是发送了一个消息队列,连线程都没有开。
  2. 但是,如果异步任务的数据特别庞大,AsyncTask这种线程池结构的优势就体现出来了。
  • AsyncTask实现的原理,和适用的优缺点

AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.

使用的优点:

l 简单,快捷

l 过程可控

使用的缺点:

l 在使用多个异步操作的同时,共同进行Ui变更时,就变得复杂起来.

l 最大并发数不超过5

  • Handler异步实现的原理和适用的优缺点

在Handler 异步实现时,涉及到 Handler, Looper, Message,Thread四个对象,实现异步的流程是主线程启动Thread(子线程)àthread(子线程)运行并生成Message-àLooper获取Message并传递给HandleràHandler逐个获取Looper中的Message,并进行UI变更。

使用的优点:

l 结构清晰,功能定义明确

l 对于多个后台任务时,简单,清晰

使用的缺点:

l 在单个后台异步处理时,显得代码过多,结构过于复杂(相对性)

AsyncTask的使用:

  • 必选方法:

1, doinbackground(params…) 后台执行,比较耗时的操作都可以放在这里。

注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作

,通常需要较长的时间。在执行过程中可以调用

Public progress(progress…)来更新任务的进度。

2, onpostexecute(result)相当于handler处理UI的方式,在这里可以使用在

doinbackground得到的结果处理操作UI。此方法在主线程执行,任务执行的结果作为此方法的参数返回。

  • 可选方法:

1, onprogressupdate(progress…) 可以使用进度条增加用户体验度。此方法在主线程执行,用户显示任务执行的进度。

2, onpreExecute() 这里是最新用户调用excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。

3, onCancelled() 用户调用取消时,要做的操作

  • AsyncTask三个状态:

pending,running,finished

  • 使用AsyncTask类,遵守的准则:

1, Task的实例必须在UI thread中创建;

2, Execute方法必须在UI thread中调用

3, 不要手动的调用onPfreexecute(),onPostExecute(result)

Doinbackground(params…),onProgressupdate(progress…)这几个方法;

4, 该task只能被执行一次,否则多次调用时将会出现异常;

AsyncTask缺陷总结:

  • 生命周期

    很多开发者会认为在一个Activity中创建的AsyncTask会随着Activity销毁而销毁,事实并非如此,AsyncTask会随着doInBackground()方法执行完毕才销毁,然后,cancel()被调用,那么onCancel会执行;否则执行postExecute方法会执行。如果在AsyncTask没有执行完毕,就销毁了Activity,AsyncTask可能会崩溃,因为它想要处理的view已经不存在了。所以,我们总是必须确保在销毁活动之前取消任务。总之,我们使用AsyncTask需要确保AsyncTask正确地取消。

    另外,即使我们正确地调用了cancle() 也未必能真正地取消任务。因为如果在doInBackgroud里有一个不可中断的操作,比如BitmapFactory.decodeStream(),那么这个操作会继续下去。

  • 内存泄漏

    如果AsyncTask未声明成静态,则会持有外部类Activity的引用,当Activity销毁之后,AsyncTask还在执行,它将在内存中依旧保持这个引用,会造成内存泄漏

  • 结果丢失

    当屏幕旋转Activity销毁重新创建(未配置android:configChanges=”orientation|screenSize”的情况)之前运行的AsyncTask会持有之前Activity的引用,这时调用onPostExecute()再去更新界面将不再生效。

  • 并行还是串行

    当想要串行执行时,直接执行execute()方法,如果需要并行执行,则要执行executeOnExecutor(Executor)。

文章目录
  1. 1. AsyncTask和Handler对比
    1. 1.1. 共同点
  2. 2. AsyncTask的使用:
  3. 3. AsyncTask缺陷总结: