AysncTask即异步任务,是Android给我们提供的一个处理异步任务的类.通过此类,可以实现UI线程和后台线程进行通讯,后台线程执行异步任务,把结果返回给UI线程。
构建AsyncTask子类的泛型参数、方法
AsyncTask<Params,Progress,Result>是一个抽象类,通常用于被继承.继承AsyncTask需要指定如下三个泛型参数:
Params:启动任务时输入的参数类型.
Progress:后台任务执行中返回进度值的类型
Result:后台任务执行完成后返回结果的类型
AsyncTask主要有如下几个回调方法:
doInBackground:必须重写,异步执行后台线程要完成的任务,耗时操作将在此方法中完成。
onPreExecute:执行后台耗时操作前被调用,通常用于进行初始化操作。
onPostExecute:当doInBackground方法完成后,系统将自动调用此方法,并将doInBackground方法返回的值传入此方法,通过此方法进行UI的更新。
onProgressUpdate:当在doInBackground方法中调用publishProgress方法更新任务执行进度后,将调用此方法,通过此方法我们可以知晓任务的完成进度。
1、构造方法做了什么?
创建一个在主线程的Handler
创建一个WorkerRunnable implements Callable 并且实现 call方法内部正是耗时操作
创建一个FutureTask 它构造接收 Callable,将mWorker实例传入,后面执行mFuture会调用它的run,在run里它调用了mWorker的call 之后一些执行一些其他...
2、为什么这么麻烦的创建了runnable和futureTask?不直接使用 线程池+Runnable?
大致了解了一下 执行Runnable无法得知执行结果 想获取执行结果 就必须通过共享变量或者线程通信来达到效果,这样太麻烦。
3、在AsyncTask中执行完任务 为什么要得知结果?
看了源码,其实用线程池+Runnable也可以做到,但是这样太麻烦了。在FutureTask任务完成后(做了些其他操作) 并且 还有几个其他的方法,cancel、get,可以取消任务,也可以get结果(如果结果还在执行会造成阻塞)
4、当execute的时候做了些什么?
我们传入N个任务参数,内部有一个SerialExecutor。调用了它的execute并且传入futureTask,内部会使用ArrayDeque管理任务。首先offer向队列中插入一个任务,这个任务具体实现run会执行我们的r.run(); finally -> scheduleNext();然后校验当前mActive==null 则执行scheduleNext。
scheduleNext中 通过mActive=mTasks.poll()取出队列头(也就是我们刚才插入的任务),并将它通过线程池execute。
执行过程: futureTask.run() -> mWorker.call() -> doInBackground 耗时操作 -> postResult 通过Message发送Result至Handler
5、AsyncTask是怎么做到更新进度的呢?
在耗时操作中调用publishProgress传入Progress参数,会在onProgressUpdate中接收到任务进度。这里就有疑问了,为什么不直接在耗时操作中更新进度呢。通过源码了解到 publishProgress 会通过内部维护的Handler将进度发送,然后接收到进度调用了我们重写的onProgressUpdate 它是主线程执行,目的就是为了进度值在主线程维护并且这样写法优雅。
网友评论