AsyncTask那些坑

作者: androider123 | 来源:发表于2017-04-27 00:02 被阅读0次

AsyncTask是一个很方便用来在主线程和工作线程切换任务的工具,但是如果用的不好会引入不少奇怪的问题

坑1:AsyncTask到底是并行还是串行

在回答这个 问题前,我们先看下官方对AsyncTask的注释,对AsyncTask有一个基本的了解

AsyncTask is designed to be a helper class around {@link Thread} and {@link Handler} * and does not constitute a generic threading framework. AsyncTasks should ideally be * used for short operations (a few seconds at the most.) If you need to keep threads * running for long periods of time, it is highly recommended you use the various APIs * provided by thejava.util.concurrentpackage such as {@link Executor}, * {@link ThreadPoolExecutor} and {@link FutureTask}

从上面AsyncTask源码注释可以看出,AsyncTask只适合做短时间操作的任务(顶多几秒),长时间的操作不建议使用,但是why?

首先我们来看下最基础的AsyncTask的运行模型

对于一个AsyncTask任务执行时3个关键函数运行的环境如上图所示,这个没有太多的疑问。

那如果多个AsyncTask同时执行会有啥不一样的么?

先上结论:

同一进程内,多个AsyncTask 直接通过execute方法执行时,在android3.0以上是串行的


这就解答了源码注释里面的一个疑问,为什么AsyncTask只适合做短时间的操作。

因为他是串行执行的,如果前面的AsyncTask阻塞了,后面的AsyncTask就全部阻塞了。。。。。(多么痛的领悟)

我们来一起捋一捋代码,看看为啥得出这样的结论

作为一个可以提交多个任务 ,且可以在工作线程和主线程切换的工具类,必须有以下几个组成


1.线程池

2.事件队列

3.handler


先看线程池

一个最简单的AsyncTask方法写法应该是

new AsyncTask().execute();

我们看下execute方法的源码如下

里面有个sDefaultExecutor,一看就是一个线程池,我们来看下定义

线程池是一个静态变量,也就是说对于同一个进程来说,只会初始化一次,同一进程内的AsyncTask都运行在此进程池中。

真相大白了,从任务队列中一个个取出任务,执行完了再scheduleNext(),串行的执行任务。所以说千万不要在AsyncTask中执行长时间的任务

坑2:AsyncTask内存泄露

相关文章

网友评论

    本文标题:AsyncTask那些坑

    本文链接:https://www.haomeiwen.com/subject/fkgwzttx.html