Android面试(六):异步消息机制之AsyncTask面试你
1. 什么是AsyncTask:
AsyncTask本质上是一个封装了线程池、工作线程和Handler的异步框架,主要是执行异步任务,由于AsyncTask里面封装了Handler,所以它可以在主线程和子线程之间灵活的切换。
2. AsyncTask的使用方法:
Params:启动任务执行的输入参数,比如HTTP请求的URL。
Progress:后台任务执行的百分比。
Result:后台任务执行最终返回的结果,比如String,Integer等。
- execute(Params... params):执行一个异步任务,需要我们手动去调用此方法,触发异步任务的执行。
- onPreExecute():在execute(params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。
- doInBackground(Params... params):在onPreExecute()完成后立即执行,用于执行耗时操作,在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。
- onProgressUpdate(Progress... values):在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。
- onPostExecute(Result result):当后台操作结束时,此方法将会被调用,计算结果将作为参数传递到此方法中,直接将结果显示到UI组件上。
3. AsyncTask的机制原理:
AsyncTask是由线程池 + 工作线程 + Handler进行构建的一个异步任务工具类。
(1) 线程池:
为了在处理多个任务时,避免创建多个线程带来内存开销,内部维护了一个线程池,管理每个线程。
内部的线程池通过ThreadPoolExecutor来动态分配固定大小的核心工作线程。这样所有的异步任务都会放到线程池,并维护每个工作线程。
(2) 工作线程:
该线程用于执行一个耗时的操作,内部通过FutureTask接收一个WorkerRunnable接口,并在接口的call方法中,执行异步任务,此时调用AsyncTask类的doInBackground()方法,做耗时操作。
由于FutureTask类实现了FutureRunnable接口,通过这个接口,在它的run方法中,执行任务。
可以方便的取消后台任务和获取后台任务的执行结果,当获取后台结果之后,将结果交给Handler了。
(3) Handler消息机制更新UI:
当FutureTask工作线程任务执行完成以后,把结果交给Handler,Handler通过发送消息,在主线程中接收消息,并调用AsyncTask类的onPostExecute(Result result)方法,来处理结果。
4. AsyncTask的注意事项:
(1) 内存泄漏:
非静态内部类持有外部类的强引用,解决方法,上一篇博客以及介绍,这里就不做过多介绍。
(2) 生命周期
需要在Activity销毁之前,调用AsyncTask的onCancelled()方法。
(3) 结果丢失
由于屏幕旋转、内存不够等异常情况,导致Activity重新创建,使用AsyncTask会引用之前的Activity,但是这个引用已经无效了,这时候调用onPostExecute(...),就不会更新界面,这就是AsyncTask结果丢失的原因。
(4) 并行or串行
在Android 1.6之前的版本中,AsyncTask都是串行的,所有的任务都会一串一串的放到线程池中。
在Android 1.6到 Android 2.3中,AsyncTask改成并行
在Android 2.3之后,又改成串行了,但是还可以执行并行,想要执行并行,可以调用executeOnExecutor(...)
喜欢本篇博客的简友们,就请来一波点赞,您的每一次关注,将成为我前进的动力,谢谢!