博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
AsyncTask的源码解读
阅读量:6910 次
发布时间:2019-06-27

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

一.概述

AsyncTask就是一个封装了 Handler+线程池 的对象。 能够自由在主线程和子线程中来回切换   ----是串行执行任务的。

二.基本概念

CPU_COUNT = Runtime.getRunTime().getAvailableProcessors() --CPU核心数

1. THREAD_POOL_EXECUTOR: 内部封装的一个线程池.  核心线程数:Math.max(2,Math.min(CPU_COUNT-1,4));

                                               最大线程数:CPU_COUNT*2+1             存活时间:30s

2. SerialExecutor: 内部封装的线程池.

3.InterHandler:   子线程与主线程的通信Handler

三.运行流程

  1.先调用execute()方法

@MainThread  public final AsyncTask
execute(Params... params) { return executeOnExecutor(sDefaultExecutor, params); }

2. sDefaultExecutor --一个SerialExecutor对象

private static class SerialExecutor implements Executor {     final ArrayDeque
mTasks = new ArrayDeque
(); Runnable mActive; public synchronized void execute(final Runnable r) { mTasks.offer(new Runnable() { //offer --添加任务 public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (mActive == null) { scheduleNext(); } } protected synchronized void scheduleNext() { if ((mActive = mTasks.poll()) != null) { //poll --取出任务 THREAD_POOL_EXECUTOR.execute(mActive); } } } --AsyncTask串行的关键; ArrayDeque --一个可扩展的双向队列

3.调用executeOnExecutor方法

@MainThread  public final AsyncTask
executeOnExecutor(Executor exec, Params... params) { if (mStatus != Status.PENDING) { //PENDING:任务还未执行过 switch (mStatus) { //RUNING:任务正在执行 case RUNNING: //任务已经完成了 throw new IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED: throw new IllegalStateException("Cannot execute task:" + " the task has already been executed " + "(a task can be executed only once)"); } } mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params; exec.execute(mFuture); return this; }

4.调用onPreExecute()方法

我们自己可以在这里做一些耗时操作的准备

5.调用了 doInBackGround(Params …params)函数

mWorker = new WorkerRunnable
() { public Result call() throws Exception { mTaskInvoked.set(true); Result result = null; try { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); //noinspection unchecked result = doInBackground(mParams); //是在子线程中执行的,在这里我们执行自己的耗时操作。 Binder.flushPendingCommands(); } catch (Throwable tr) { mCancelled.set(true); throw tr; } finally { postResult(result); } return result; } };

6.postResult()和publishProgress()方法

将得到的结果返回给主线程private Result postResult(Result result) {         @SuppressWarnings("unchecked")         Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,                 new AsyncTaskResult
(this, result)); message.sendToTarget(); return result; }将任务下载的进度传给主线程 @WorkerThread protected final void publishProgress(Progress... values) { if (!isCancelled()) { getHandler().obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult
(this, values)).sendToTarget(); } }

7.InterHandler

private static class InternalHandler extends Handler {     public InternalHandler(Looper looper) {         super(looper);     }    @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})     @Override     public void handleMessage(Message msg) {         AsyncTaskResult
result = (AsyncTaskResult
) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT: // There is only one result result.mTask.finish(result.mData[0]); break; case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); break; } } }

8.onProgressUpdate()可以更新进度

需要手动在doInBackGround()方法里面调用publishProgress()方法

9.onPostResult()方法,任务下载完毕之后得到的结果

自己重写,可以在任务下载之后进行一些操作

四.实际操作

class DownAsyncTask extends AsyncTask
{ protected Result doInBackGround(Params … params){ down()//耗时操作 } //可重写 主要发生在任务之前 主线程中 protected void onPreExecute(){ } //主要表现任务的完成进度 需要在doInBackGround中调用 publishProgress()方法 protected void onProgressUpdate(Param param){ } //任务完成之后的调用方法 protected void onPostExecute(Result result){ }}

转载于:https://www.cnblogs.com/xiongbo753/p/9805632.html

你可能感兴趣的文章
全栈工程师就是一棵歪脖子树
查看>>
对于设计模式最近观感的浅薄理解
查看>>
Spring中AOP使用——配置xml方式
查看>>
JavaScript是如何工作的:深入类和继承内部原理 + Babel和TypeScript 之间转换
查看>>
.net reactor使用教程(一)——界面各功能说明
查看>>
腾讯 AI Lab 正式开源PocketFlow,让深度学习放入手机!
查看>>
教你在Docker上不到2分钟建立一个多模型数据库!
查看>>
python输入输出语句
查看>>
HTTPS时代的到来是大势所趋!阿里云CDN如何助力企业网站进入HTTPS时代
查看>>
Linux 积极使用swap空间
查看>>
等待事件之Log File Sync
查看>>
php测试kafka
查看>>
js获取两个日期之间时间差(天数)
查看>>
Memcached 简介
查看>>
虚拟化二、Xen虚拟化技术
查看>>
Oracle 11g数据库随系统自动启动与关闭的设置方法
查看>>
天猫与九大快递合作 价格热战之后的冷静竞争
查看>>
git pull force
查看>>
scons用户手册
查看>>
使用new操作符来调用一个构造函数的时候发生了什么
查看>>