AsyncTask理解

AsyncTask理解AsyncTask 用法以下就是 AsyncTask 使用方法 AsyncTask 源码解析 asyncTask execute 执行开始初始化一个 AsyncTask 调用无参构造器实例化了一个 WorkerRunnab 对象 mWorker 实际是一个 Callable 实例化了一个 FutureTask 对象 mfuture 实际是一个 Runnable 传入参数 mWorker 这两个后面会用到然后 execute 方

AsyncTask用法

以下就是AsyncTask使用方法

AsyncTask理解

AsyncTask源码解析


asyncTask.execute()执行开始 初始化一个AsyncTask调用无参构造器

AsyncTask理解

实例化了一个WorkerRunnable对象 mWorker实际是一个Callable

AsyncTask理解

AsyncTask理解

实例化了一个FutureTask对象 mfuture实际是一个Runnable,传入参数mWorker ,这两个后面会用到

AsyncTask理解

然后execute方法里面调用了executeOnExecutor()方法

AsyncTask理解

execute()只能调用一次的原因也在这里面,RUNNING表示正在运行 FINISHED 已执行完毕。
onPreExecute()方法是第一个调用,在这个方法里面可以做一些初始化的操作。
exec.execute(mFuture) exec 可能会有人疑问这个是什么?
我们先来看exec :
exec 就是sDefaultExecutor实际上就是一个串行的线程池 一个进程中所有的AsyncTask都在这个线程池中顺序执行,SerialExecutor可以从这个静态内部类分析AsyncTask执行的过程:

AsyncTask理解


首先会把AsyncTask参数封装成FutureTask,实际上FutureTask是一个Runnable
然后把FutureTask交给SerialExecutor的execute方法,首先将任务插入mTasks中。如果当前并没有任务执行,就会调用scheduleNext()方法取出下一个任务执行,从这个方法可以看出AsyncTask默认是串行执行的。
实际上来说SerialExecutor并没有真正的执行任务,它只是为了保证了任务串行执行
真正执行任务的是THREAD_POOL_EXECUTOR?


AsyncTask理解



THREAD_POOL_EXECUTOR是个线程池开启了一定的核心线程和工作线程。
然后调用线程池的execute()方法执行具体的耗时任务。
实际上就是调用了FutureTask的run()方法中的c.call(),c就是WorkerRunnable,所以就执行到了
mWorker的call()方法

AsyncTask理解

现在就执行到了mWorker的call方法,先后执行了doInBackground()、postRelust()方法
AsyncTask理解
postRelust方法中通过Handler将结果发送到UI线程进行页面数据更新

AsyncTask理解

1、我们可以看到如果收到的消息是MESSAGE_POST_RESULT,表明执行完了耗时任务,调用finish方法

AsyncTask理解

如果任务已经取消了,回调onCancelled()方法,否则回调 onPostExecute()方法。
2、如果收的的消息是MESSAGE_POST_PROGRESS,则调用onProgressUpdate方法更新进度。


注:InternalHandler是一个静态内部类,为了能使工作线程切换到UI线程,因此必须在UI线程加载,这就要求AsyncTask必须在主线程执行。
因为默认的是串行执行,如果需要并行执行可以跳过SerialExecutor直接使用executeOnExecutor()方法执行任务


使用不当
1.)内存泄漏
如果AsyncTask被声明为Activity/Fragment的非静态的内部类,那么AsyncTask会保留一个对创建了AsyncTask的Activity的引用。如果Activity/Fragment已经被销毁,AsyncTask的后台线程还在执行,它将继续在内存里保留这个引用,导致Activity无法被回收,引起内存泄露,所以最好在Activity/Fragment的onDestory()调用 cancel(boolean)。
2.) 结果丢失
屏幕旋转或Activity在后台被系统杀掉等情况会导致Activity的重新创建,之前运行的AsyncTask(非静态的内部类)会持有一个之前Activity的引用,这个引用已经失效,这时调用onPostExecute()再去更新界面将不再生效。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/227900.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午8:15
下一篇 2026年3月16日 下午8:16


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号