AsyncTask<Params,Progress,Result>是一个抽象类:Params执行任务要输入的参数的类型(URL等等),Progress后台完成任务进度值的类型,Result后台任务结束返回结果的类型;
一般在主线程中定义这个内部类(共享组件等等),实现这个类要自定义类继承它,终点重写四个方法:
1.DoinBackground():耗时任务执行的地方;
2.onpreexecute():一般用来显示任务进度条,最先执行
3.onprogressUpdate():一般用来更新进度条的进度值;
4.onPostExecute():当任务完成时,将结果返回在这个方法中;
创建这个AsyncTask子类对象,并实现execute(params)方法来开始执行任务;
注意:必须在UI中创建AsyncTask对象和实现它的execute方法;每个AsyncTask只能被执行一次,不能多次;
AsyncTask类似于Handle,它更轻量级,封装了线程和Handle,不适合执行耗时长的任务;
AsyncTask通过一个BlockingQuery<Runnable>储存任务,任务在Android3.0以前是并行任务执行器,在3.0之后是串行任务执行器,利用Thread_Pool_Executor默认提供的128个线程处理任务;
配置后的线程池如下:
1.核心线程数等于CPU核心数+1;
2.线程池的最大线程数为CPU核心数的2倍+1;
3.任务队列容量为128;
源码分析:
主要由线程池+Hanlder实现的
线程池
当执行execute()方法,会调用executeOnExecutor方法,将参数赋值给一个worker对象,即Callable任务,最终被封装成FutureTask进行任务的执行,执行的时候通过使用SERIAL_EXECUTOR,即一个串行执行器,通过scheduleNext不断去取出它内部单项任务队列中的task,并交给线程池进行任务处理
new ThreadPoolExecutor( 1, 20, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), sThreadFactory)
交给上述这样的一个线程池进行处理之后,把worker对象计算出来的结果通过handler发送消息,并最终执行onPostExecute进行结果返回;
注:1.execute中executeOnExecutor调用了onPreExecute,该方法是UI线程中执行,所以execute一定要在UI线程中执行;
2.一个AysncTask只能执行一次,如下图因为execute前会判断task的状态是否执行过或正在执行;
3.AsyncTask
是封装了Thread
和Handler
,为了能够将执行环境切换到主线程这就要求源码中的Handler
对象绑定主线程因此AsyncTask
对象应该在主线程创建;
4.AysncTask默认是单线程执行,如果想让它多线程执行,可以使用executeOnExecutor(Executor exec, Params... params),传一个自定义的Executor进行改造;