博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
动手实现AsyncTask v1.1
阅读量:5895 次
发布时间:2019-06-19

本文共 4746 字,大约阅读时间需要 15 分钟。

AsyncTask是后台执行操作在UI线程发布结果的对象,很轻松的使用UI线程,用于耗时较短的后台操作。

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");...    AsyncTask
asyncTask = 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(); } };复制代码

转载地址:http://jpisx.baihongyu.com/

你可能感兴趣的文章
R语言中的Apriori关联规则的使用
查看>>
Palindrome Number
查看>>
正则学习1
查看>>
idea导入myeclipes项目、运行项目
查看>>
安装centos 6.7&7.4
查看>>
m2eclipse(maven插件)报错解决
查看>>
Two Dimensional Array Program in C++
查看>>
数据库连接查询操作
查看>>
Win10 mongodb 作为系统服务启动
查看>>
(转)Linq DataTable的修改和查询
查看>>
Java中泛型Class<T>、T与Class<?>
查看>>
python实现wc功能
查看>>
Android--全局变量 很好很强大
查看>>
交换排序之冒泡算法的C语言实现 2017-3-19更新
查看>>
Linux环境下安装JDK
查看>>
第六周作业——预习题
查看>>
php 简单操作数据库
查看>>
相对单位rem
查看>>
TreeSet
查看>>
vc CListCtrl使用
查看>>