搞清楚---AsyncTask

行文之目的:整理AsyncTak知识点,剖析之。

首先从Android3.0开始,系统要求网络访问必须在子线程中进行,否则网络访问将会失败并抛出NetworkOnMainThreadException这个异常,这样做是为了避免主线程由于耗时操作所阻塞从而出现ANR现象。AsyncTask封装了线程池和Handler;AsyncTask有两个线程池:SerialExecutorTHREAD_POOL_EXECUTOR;前者是用于任务的排队,默认是串行的线程池,后者用于真正的执行任务;AsyncTask还有一个Handler,InternalHandler,用于将执行环境从线程池切换到主线程。AsyncTask内部就是通过InternalHandler来发送任务执行的进度以及执行结束等消息。AsyncTask排队执行过程:系统先把参数Params封装为FutureTask对象,它相当于Runnable,接着FutureTask交给SerialExcutor的execute方法,它先把FutureTask插入到任务队列tasks中,如果这个时候没有正在活动的AsyncTask任务,那么就会执行下一个AsyncTask任务,同时当一个AsyncTask任务执行完毕之后,AsyncTask会继续执行其他任务直到所有任务都被执行完为止。 关于线程池,AsyncTask对应的线程池ThreadPoolExecutor都是进程范围内共享的,都是static的,所以是AsyncTask控制着进程范围内所有的子类实例。由于这个限制的存在,当使用默认线程池时,如果线程数超过线程池的最大容量,线程池就会爆掉(3.0默认串行执行,不会出现这个问题)。针对这种情况。可以尝试自定义线程池,配合AsyncTask使用。
public abstract class AsyncTask

Params
执行后台任务时传入的参数类型
Progress
后台任务执行进度的类型
Result
后台任务执行完毕返回的结果类型

AsyncTask是一个抽象类,使用时定义一个实体类继承之,override其方法即可。
注意问题:
AsyncTask默认是串行执行,若要并发执行则要调用
executeOnExecutor(Executor exec, Params... params)方法指定线程池执行
也可以通过setDefaultExecutor(Executor exec)设置默认线程池

AsyncTask作为内部类的时候最好声明为静态内部类,并以弱引用的形式引用Activity,防止内存泄漏

AsyncTask中的后台任务应该使用isCancelled()判断任务是否已经取消,防止做无用功,
任务中有一个循环,可以在循环条件中加入判断

Activity销毁的时候最好调用AsyncTask的cancel()方法,防止更新已经被回收的view

Activity重建时候应注意对AsyncTask的维护
Android 屏幕旋转 处理 AsyncTask 和 ProgressDialog 的最佳方案

你可能感兴趣的:(搞清楚---AsyncTask)