android中实现异步任务有两种方式Handler和AsyncTask
handler需要为每个任务创建一个新的线程任务完成后通过handler 实例向ui线程发送消息完成界面的更新
AsyncTask内部也是使用handler传递消息 而且是基于线程池的
一个异步任务的执行一般包括以下几个步骤:
1.execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。
2.onPreExecute(),在 execute(Params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。
3.doInBackground(Params... params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。
4.onProgressUpdate(Progress... values),在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。
5.onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。
在使用的时候,有几点需要格外注意:
1.异步任务的实例必须在UI线程中创建。
2.execute(Params... params)方法必须在UI线程中调用。
3.不要手动调用onPreExecute(),doInBackground(Params... params),onProgressUpdate(Progress... values),onPostExecute(Result result)这几个方法。
4.不能在doInBackground(Params... params)中更改UI组件的信息。
5.一个任务实例只能执行一次,如果执行第二次将会抛出异常。
asyncTask源码分析
AsyncTask是对Thread+Handler良好的封装
通过查看源码我们可以看到关键几个步骤的方法都在其中。
1、doInBackground(Params... params)是一个抽象方法,我们继承AsyncTask时必须覆写此方法;
2、onPreExecute()、onProgressUpdate(Progress... values)、onPostExecute(Result result)、onCancelled()这几个方法体都是空的,我们需要的时候可以选择性的覆写它们;
3、publish Progress(Progress... values)是final修饰的,不能覆写,只能去调用,我们一般会在doInBackground(Params... params)中调用此方法来更新进度条;
AsyncTask的初始状态为PENDING,代表待定状态,RUNNING代表执行状态,FINISHED代表结束状态
AsyncTask工作原理
execute方法调用executeOnExecutor方法
系统会把AsyncTask的参数封装为FutureTask对象 FutureTask是一个并发类
AsyncTask中有两个线程池SerialExecutor和THREAD_POOL_EXECUTOR;和一个Handler(internalHandler)
SerialExecutor用于任务的排队 THREAD_POOL_EXECUTOR用于真正的执行任务;
Handler用于将执行环境从线程池切换到主线程
android4.1.1上执行是串行执行 2.3.3上执行是并行执行的;
通过源码得知
只是初始化了两个变量,mWorker和mFuture,并在初始化mFuture的时候将mWorker作为参数传入。mWorker是一个Callable对象,mFuture是一个FutureTask对象.想要启动某一个任务,就需要调用该任务的execute()方法
在第15行调用了onPreExecute()方法
在第17行调用了Executor的execute()方法 SerialExecutor类中也有一个execute()方法 在doInBackground()方法中调用publish Progress()方法才可以从子线程切换到UI线程
这里规定同一时刻能够运行的线程数为5个,线程池总大小为128。也就是说当我们启动了10个任务时,只有5个任务能够立刻执行,另外的5个任务则需要等待,当有一个任务执行完毕后,第6个任务才会启动,以此类推。而线程池中最大能存放的线程数是128个,当我们尝试去添加第129个任务时,程序就会崩溃