AsyncTask原理
-
AsyncTas类初始化sDefaultExecutor和sHandler变量,用于执行后台执行任务和分发消息给主线程
-
AsyncTask对象创建时实现后台执行函数doInBackground()和发布UI结果的回调函数onPostExecute()
-
构造AsyncTask时
-
构建类型为WorkerRunnable的mWork对象,执行doInBackground(),然后发送结束消息给sHandler
-
构建类型FutureTask的mFuture对象,以mWork为回调参数,并重写任务结束回调方法done(),如果上面没有发送消息没有成功会再次发给sHandler
-
mWork和mFuture中发送消息都调用postResult(),message的obj指向的是AsyncTaskResult对象,其包含AsyncTask对象和消息类型标记
-
execute()启动时在执行线程池处理任务之前先调用onPreExecute()
-
mFuture进入sDefaultExecutor线程池任务队列消费
-
任务执行结束调用FutureTask的done()方法,将执行完毕消息通过postResult()发送给sHandler
-
sHandler收到消息根据what标记分别调用asyncTask对象的发布结果回调方法和更新UI进度方法
注明: AsyncTask必须在主线程中创建 后台执行回调调用publishProgress()就是发送更新进度消息给sHandler
动手实现
public abstract class AsyncTask{ private static final int MESSAGE_POST_RESULT = 1;//结束标记 private static final int MESSAGE_POST_PROGRESS = 2;//更新进度标记 private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();//cpu核心数 //最少2个或者4个核心线程 //cpu核心数少一个线程,以免饱和 private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4)); private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; private static final int KEEP_ALIVE_SECONDS = 30; //线程创建工厂 private static final ThreadFactory sThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); public Thread newThread(Runnable r) { 参数2为线程名字 return new Thread(r, "AsyncTask #" + mCount.getAndIncrement()); } }; //最多容纳128个任务,再多任务就会被阻塞 private static final BlockingQueue sPoolWorkQueue = new LinkedBlockingQueue (128); static { //初始化线程执行器配置 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory); threadPoolExecutor.allowCoreThreadTimeOut(true); sDefaultExecutor = threadPoolExecutor;//暂不使用哪个串行执行的执行器 } private static volatile Executor sDefaultExecutor; private static InternalHandler sHnadler; //不适用懒加载直接使用 static { sHnadler = new InternalHandler(); } private final WorkerRunnable mWorker; private final FutureTask mFuture; public AsyncTask() { //mWorker的参数在execute的时候补上 mWorker = new WorkerRunnable () { @Override public Result call() throws Exception { Result result = doInBackground(mParams);//调用后台执行操作 postResult(result);//通知handler调用发布结果回调 return result; } }; mFuture = new FutureTask (mWorker);//暂不包装二次检查发送 } //发送结束消息给handler private void postResult(Result result) { Message message = Message.obtain(); message.what = MESSAGE_POST_RESULT; message.obj = new AsyncTaskResult(this, result); } //发送更新消息给handler protected void publishProgress(Progress... values) { Message message = Message.obtain(); message.what = MESSAGE_POST_PROGRESS; message.obj = new AsyncTaskResult(this, values); } //执行任务 public void execute(Params... values) { onPreExecute(); mWorker.mParams = values; sDefaultExecutor.execute(mFuture); } protected void onPreExecute() { } //后台操作回调 protected abstract Result doInBackground(Params... var1); //发布结果回调 protected void onPostExecute(Result result) { } //进度回调 protected void onProgressUpdate(Progress... values) { } //主线程处理消息调用asyncTask的回调 private static class InternalHandler extends Handler { public InternalHandler() { super(Looper.getMainLooper()); } @Override public void handleMessage(Message msg) { AsyncTaskResult result = (AsyncTaskResult) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT: result.mTask.onPostExecute(result.mData[0]);//发布结果回调 break; case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData);//更新进度回调 break; } } } //通过线程传递给doInBackground用户定义好的参数 private static abstract class WorkerRunnable implements Callable { Params[] mParams; } //消息携带类 private static class AsyncTaskResult { AsyncTask mTask;//消息发送所属AsyncTask Result[] mData;//结果参数 public AsyncTaskResult(AsyncTask mTask, Result... mData) { this.mTask = mTask; this.mData = mData; } }}复制代码
使用
asyncTask.execute("http://www.baidu.com");... AsyncTaskasyncTask = new AsyncTask () { @Override protected String doInBackground(String... strings) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return "hello"; } @Override protected void onPostExecute(String value) { super.onPostExecute(value); Toast.makeText(MainActivity.this, value + " over", Toast.LENGTH_SHORT).show(); } };复制代码