AsyncTask是android提供的轻量级的异步类。比Handler更轻量级一些,适用于简单的异步处理。android
AsyncTask内部封装了Thread和Handler,简化Thread+Handler,可让咱们在后台进行计算而且把计算的结果及时更新到UI上。并发
AsyncTask并非像多个线程那样彻底并行执行的。异步
优势:ide
简单,快捷ui
过程可控url
结构清晰,功能定义明确spa
对于多个后台任务时,简单,清晰.net
缺点:线程
在使用多个异步操做和并须要进行Ui变动时,就变得复杂起来.设计
在单个后台异步处理时,显得代码过多,结构过于复杂(相对性)
AsyncTask中维护着一个长度为128的线程池,同时能够执行5个工做线程,还有一个缓冲队列,当线程池中已有128个线程,缓冲队列已满时,若是此时向线程提交任务,将会抛出RejectedExecutionException。
解决:由一个控制线程来处理AsyncTask的调用判断线程池是否满了,若是满了则线程睡眠不然请求AsyncTask继续处理。
AsyncTask直接继承于Object类,位置为android.os.AsyncTask。要使用AsyncTask工做咱们要提供三个泛型参数,并重载几个方法(至少重载一个)。
AsyncTask定义了三种泛型类型 Params,Progress和Result。
Params 启动任务执行的输入参数,好比HTTP请求的URL。
Progress 后台任务执行时,若是须要在界面上显示当前的进度,则使用这里指定的泛型做为进度单位。
Result 后台执行任务最终返回的结果,好比String。
doInBackground(Params…) 后台执行,比较耗时的操做均可以放在这里。注意这里不能直接操做UI。此方法在后台线程执行,完成任务的主要工做,一般须要较长的时间。在执行过程当中能够调用publicProgress(Progress…)来更新任务的进度。
onPostExecute(Result) 至关于Handler 处理UI的方式,在这里面可使用在doInBackground 获得的结果处理操做UI。 此方法在主线程执行,任务执行的结果做为此方法的参数返回
onProgressUpdate(Progress…) 可使用进度条增长用户体验度。 此方法在主线程执行,用于显示任务执行的进度。当在后台任务中调用了publishProgress(Progress...)方法后,这个方法就很快会被调用,方法中携带的参数就是在后台任务中传递过来的。
onPreExecute() 这里是最终用户调用Excute时的接口,当任务执行以前开始调用此方法,能够在这里显示进度对话框。
onCancelled() 用户调用取消时,要作的操做
AsyncTask的类必须在UI线程加载(从4.1开始系统会帮咱们自动完成)
AsyncTask对象必须在UI线程建立
execute方法必须在UI线程调用
不要在你的程序中去直接调用onPreExecute(), onPostExecute, doInBackground, onProgressUpdate方法
一个AsyncTask对象只能执行一次,即只能调用一次execute方法,不然会报运行时异常
AsyncTask不是被设计为处理耗时操做的,耗时上限为几秒钟,若是要作长耗时操做,强烈建议你使用Executor,ThreadPoolExecutor以及FutureTask
在1.6以前,AsyncTask是串行执行任务的,1.6的时候AsyncTask开始采用线程池里处理并行任务,可是从3.0开始,为了不AsyncTask所带来的并发错误,AsyncTask又采用一个线程来串行执行任务
public class DownloadFilesTask extends AsyncTask<URL, Integer, Long> { protected Long doInBackground(URL... urls) { int count = urls.length; long totalSize = 0; for (int i = 0; i < count; i++) { totalSize += Downloader.downloadFile(urls[i]); publishProgress((int) ((i / (float) count) * 100)); // Escape early if cancel() is called if (isCancelled()) break; } return totalSize; } protected void onProgressUpdate(Integer... progress) { setProgressPercent(progress[0]); } protected void onPostExecute(Long result) { showDialog("Downloaded " + result + " bytes"); } }
AsyncTask在4.1.1及是串行的,在2.3.3应该是并行的
@TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override public void onClick(View v) { if (v == mButton) { new MyAsyncTask("AsyncTask#1").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,""); new MyAsyncTask("AsyncTask#2").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,""); new MyAsyncTask("AsyncTask#3").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,""); new MyAsyncTask("AsyncTask#4").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,""); new MyAsyncTask("AsyncTask#5").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,""); } } private static class MyAsyncTask extends AsyncTask<String, Integer, String> { private String mName = "AsyncTask"; public MyAsyncTask(String name) { super(); mName = name; } @Override protected String doInBackground(String... params) { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } return mName; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Log.e(TAG, result + "execute finish at " + df.format(new Date())); } }