【Android 异步操作】AsyncTask 异步任务 ( AsyncTask 异步任务执行方法 execute 方法相关源码解析 )

本文涉及的产品
云解析DNS-重点域名监控,免费拨测 20万次(价值200元)
简介: 【Android 异步操作】AsyncTask 异步任务 ( AsyncTask 异步任务执行方法 execute 方法相关源码解析 )

文章目录

一、AsyncTask 异步任务执行方法 execute() 引入

二、AsyncTask 异步任务执行方法 execute()

三、sDefaultExecutor 线程池解析

四、executeOnExecutor 方法解析

五、AsyncTask 异步任务执行方法 execute() 相关源码注释





一、AsyncTask 异步任务执行方法 execute() 引入


上一篇博客中 【Android 异步操作】AsyncTask 异步任务 ( 参数简介 | 方法简介 | 使用方法 | AsyncTask 源码分析 ) , 讲解了 AsyncTask<Params, Progress, Result> 异步任务的构造函数 ;


异步任务执行有两个方法 :


构造异步任务 : 调用 AsyncTask 的构造函数 , 创建 AsyncTask 异步任务对象 ;

执行异步任务 : 调用 AsyncTask 异步任务对象的 execute() 方法 , 执行异步任务 ;

本篇博客中讲解执行函数 AsyncTask<Params, Progress, Result> execute(Params… params) ;


// 1. 创建 AsyncTask 异步任务
MyAsyncTask mMyAsyncTask = new MyAsyncTask();
// 2. 执行 AsyncTask 异步任务
mMyAsyncTask.execute();





二、AsyncTask 异步任务执行方法 execute()


AsyncTask<Params, Progress, Result> execute(Params… params) 方法作用 : AsyncTask 异步任务的 execute() 函数作用就是提交任务 , 其提交的任务就是 FutureTask , 其使用的是 线程池 提交任务 ;



① 参数 : 使用指定的参数 , 执行任务 ;


② 返回值 : 这个任务返回 AsyncTask<Params, Progress, Result> 本身对象 , 以便调用者可以持有该异步任务的引用 ;


③ 任务调度 : 该方法在队列上调度一个任务 , 该任务在一个单独的后台线程 , 或线程池中执行 ; 第一次引入后 , 异步任务在单独后台线程中被串行执行 ;


④ 不同版本的执行任务载体 :


Android 1.6(API 级别 4)及以下的版本是在一个后台线程中串行执行 ;

Android 2.0(API 级别 5)及以上的版本是在线程池中串行执行 ;

Android 3.0(API 级别 11)及以上的版本有回复到在一个后台线程中串行执行 ;

在该类中 , 最终调用了 executeOnExecutor() 方法 , 使用 sDefaultExecutor 默认串行线程池执行任务 ;


public abstract class AsyncTask<Params, Progress, Result> {
    @MainThread
    public final AsyncTask<Params, Progress, Result> execute(Params... params) {
        return executeOnExecutor(sDefaultExecutor, params);
    }
}


如果同时调用 AsyncTask 异步任务的 execute() 函数执行任务 , 其任务会逐个串行执行 , 不是并行的 ;


AsyncTask<Params, Progress, Result> 对象的 execute() 执行的任务是有序的 ;






三、sDefaultExecutor 线程池解析


上述执行异步任务的方法 executeOnExecutor() , 传入了 sDefaultExecutor 线程池作为参数 , 本节分析 sDefaultExecutor 线程池 ;



sDefaultExecutor 是成员变量 , 其声明类型是 Executor , 实际类型是自定义的线程池 SerialExecutor() ;



SerialExecutor 是一个线程池 , 执行任务 , 每次只执行一个任务 , 按照串行顺序执行 ; 该序列对于特定进程来说是全局的 , 即一个进程只有一个该序列 ;



在该线程池中 , 维护了如下两个成员 :


任务队列 ArrayDeque mTasks

当前执行任务 Runnable mActive


该线程池中 void execute(final Runnable r) 执行任务方法 :


执行当前传入的任务 : 自己创建一个 Runnable , 在其 run() 方法中执行传入的参数的 r 的 run() 方法 ;

执行下一个任务 : 执行完毕当前任务后 , 调用 scheduleNext() 执行下一个任务


scheduleNext() 方法 用于执行下一个任务 , 从队列中取出一个任务 , 如果取出的任务不为空 , 那么就执行该任务 ; 调用 SerialExecutor 类的 execute(final Runnable r) 方法执行该任务 ;


public abstract class AsyncTask<Params, Progress, Result> {
    private static final String LOG_TAG = "AsyncTask";
    /**
     * 自定义线程池 ; 
     * 一个线程池 , 执行任务 , 每次只执行一个任务 , 按照串行顺序执行 ; 
     * 该序列对于特定进程来说是全局的 , 即一个进程只有一个该序列 ; 
     */
    public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
    @UnsupportedAppUsage
    private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
    /**
     * 自定义线程池 ; 
     * 一个线程池 , 执行任务 , 每次只执行一个任务 , 按照串行顺序执行 ; 
     * 该序列对于特定进程来说是全局的 , 即一个进程只有一个该序列 ; 
     */
    private static class SerialExecutor implements Executor {
      // 任务队列 
        final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
        // 当前执行的任务 
        Runnable mActive;
  // 执行任务
        public synchronized void execute(final Runnable r) {
          // 自己创建一个 Runnable , 在其 run() 方法中执行如下方法 : 
          // 传入的 execute(final Runnable r) 方法参数的 r 的 run() 方法 ; 
            mTasks.offer(new Runnable() {
                public void run() {
                    try {
                        r.run();
                    } finally {
                      // 执行完毕当前任务后 , 执行下一个任务
                        scheduleNext();
                    }
                }
            });
    // 如果当前任务为空 , 那么执行下一个任务 
            if (mActive == null) {
                scheduleNext();
            }
        }
  /**
   * 执行下一个任务 
   * 从队列中取出一个任务 , 如果取出的任务不为空 , 那么就执行该任务 ; 
   * 调用 SerialExecutor 类的 execute(final Runnable r) 方法执行该任务 ; 
   */
        protected synchronized void scheduleNext() {
            if ((mActive = mTasks.poll()) != null) {
              // 执行队列中的任务的操作 
                THREAD_POOL_EXECUTOR.execute(mActive);
            }
        }
    }
}





四、executeOnExecutor 方法解析


executeOnExecutor 方法是异步任务执行的核心方法 ;



执行流程如下 :



① 判定合法性 : AsyncTask 异步任务只能执行一次 , 必须确保该 AsyncTask 异步任务没有执行过 , 如果执行过直接抛出异常 ;


② 设置运行状态 : 将该异步任务状态设置成 Status.RUNNING 状态 , 防止第二次被执行 ;


③ 主线程初始化 : 执行 onPreExecute() 方法 , 用户可以在该方法中初始化 UI , 该操作在 UI 主线程中运行 ;


④ 子线程后台任务执行 : 执行 FutureTask 中的 Callable 任务 , 也就是异步任务 , 该操作在子线程中运行 ;



public abstract class AsyncTask<Params, Progress, Result> { 
    /**
     * 使用指定的参数 , 执行任务 ; 
     * 这个任务返回 AsyncTask<Params, Progress, Result> 本身对象 , 
     * 一遍调用者可以持有该异步任务的引用 ; 
     * 
     * 该方法通常与 THREAD_POOL_EXECUTOR 一同使用 , 允许多个任务在一个线程池中串行执行 , 
     * 该线程池由 AsyncTask 异步任务管理 , 也可以使用自己的线程池定制相关行为 ; 
     */
    @MainThread
    public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
            Params... params) {
        // 首先判定当前状态是否合法 , 确保该 AsyncTask 异步任务没有执行过 , 
        // 每个 AsyncTask 异步任务创建后只能执行一次 ; 
        if (mStatus != Status.PENDING) {
            switch (mStatus) {
                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;
  // 执行 doInBackground() 之前执行的方法 
        onPreExecute();
  // 设置 WorkerRunnable 的 Params[] mParams 参数
        mWorker.mParams = params;
        // 执行 FutureTask 中的 Callable 任务
        exec.execute(mFuture);
        return this;
    }
}






五、AsyncTask 异步任务执行方法 execute() 相关源码注释


public abstract class AsyncTask<Params, Progress, Result> {
    private static final String LOG_TAG = "AsyncTask";
    /**
     * 自定义线程池 ; 
     * 一个线程池 , 执行任务 , 每次只执行一个任务 , 按照串行顺序执行 ; 
     * 该序列对于特定进程来说是全局的 , 即一个进程只有一个该序列 ; 
     */
    public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
    @UnsupportedAppUsage
    private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
    /**
     * 自定义线程池 ; 
     * 一个线程池 , 执行任务 , 每次只执行一个任务 , 按照串行顺序执行 ; 
     * 该序列对于特定进程来说是全局的 , 即一个进程只有一个该序列 ; 
     */
    private static class SerialExecutor implements Executor {
      // 任务队列 
        final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
        // 当前执行的任务 
        Runnable mActive;
  // 执行任务
        public synchronized void execute(final Runnable r) {
          // 自己创建一个 Runnable , 在其 run() 方法中执行如下方法 : 
          // 传入的 execute(final Runnable r) 方法参数的 r 的 run() 方法 ; 
            mTasks.offer(new Runnable() {
                public void run() {
                    try {
                        r.run();
                    } finally {
                      // 执行完毕当前任务后 , 执行下一个任务
                        scheduleNext();
                    }
                }
            });
    // 如果当前任务为空 , 那么执行下一个任务 
            if (mActive == null) {
                scheduleNext();
            }
        }
  /**
   * 执行下一个任务 
   * 从队列中取出一个任务 , 如果取出的任务不为空 , 那么就执行该任务 ; 
   * 调用 SerialExecutor 类的 execute(final Runnable r) 方法执行该任务 ; 
   */
        protected synchronized void scheduleNext() {
            if ((mActive = mTasks.poll()) != null) {
              // 执行队列中的任务的操作 
                THREAD_POOL_EXECUTOR.execute(mActive);
            }
        }
    }
    /**
     * 使用指定的参数 , 执行任务 ; 
     * 这个任务返回 AsyncTask<Params, Progress, Result> 本身对象 , 
     * 一遍调用者可以持有该异步任务的引用 ; 
     * 
     * 该方法在队列上调度一个任务 , 该任务在一个单独的后台线程  , 或线程池中执行 ; 
     * 第一次引入后 , 异步任务在单独后台线程中被串行执行 ; 
     * Android 1.6(API 级别 4)及以下的版本是在一个后台线程中串行执行 ; 
     * Android 2.0(API 级别 5)及以上的版本是在线程池中串行执行 ; 
     * Android 3.0(API 级别 11)及以上的版本有回复到在一个后台线程中串行执行 ; 
     *
     * <p>改方法必须在 UI 线程中调用 
     *
     * @param 要执行的任务的参数.
     *
     * @return 返回异步任务 AsyncTask 本身 .
     */
    @MainThread
    public final AsyncTask<Params, Progress, Result> execute(Params... params) {
        return executeOnExecutor(sDefaultExecutor, params);
    }
    /**
     * 使用指定的参数 , 执行任务 ; 
     * 这个任务返回 AsyncTask<Params, Progress, Result> 本身对象 , 
     * 一遍调用者可以持有该异步任务的引用 ; 
     * 
     * 该方法通常与 THREAD_POOL_EXECUTOR 一同使用 , 允许多个任务在一个线程池中串行执行 , 
     * 该线程池由 AsyncTask 异步任务管理 , 也可以使用自己的线程池定制相关行为 ; 
     */
    @MainThread
    public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
            Params... params) {
        // 首先判定当前状态是否合法 , 确保该 AsyncTask 异步任务没有执行过 , 
        // 每个 AsyncTask 异步任务创建后只能执行一次 ; 
        if (mStatus != Status.PENDING) {
            switch (mStatus) {
                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;
  // 执行 doInBackground() 之前执行的方法 
        onPreExecute();
  // 设置 WorkerRunnable 的 Params[] mParams 参数
        mWorker.mParams = params;
        // 执行 FutureTask 中的 Callable 任务
        exec.execute(mFuture);
        return this;
    }
}




目录
相关文章
|
7月前
|
XML 搜索推荐 Android开发
Android改变进度条控件progressbar的样式(根据源码修改)
本文介绍了如何基于Android源码自定义ProgressBar样式。首先分析了系统源码中ProgressBar样式的定义,发现其依赖一张旋转图片实现动画效果。接着分两步指导开发者实现自定义:1) 模仿源码创建一个旋转动画XML文件(放置在drawable文件夹),修改图片为自定义样式;2) 在UI控件中通过`indeterminateDrawable`属性应用该动画。最终实现简单且个性化的ProgressBar效果,附带效果图展示。
450 2
|
8月前
|
NoSQL 应用服务中间件 PHP
布谷一对一直播源码android版环境配置流程及功能明细
部署需基于 CentOS 7.9 系统,硬盘不低于 40G,使用宝塔面板安装环境,包括 PHP 7.3(含 Redis、Fileinfo 扩展)、Nginx、MySQL 5.6、Redis 和最新 Composer。Swoole 扩展需按步骤配置。2021.08.05 后部署需将站点目录设为 public 并用 ThinkPHP 伪静态。开发环境建议 Windows 操作系统与最新 Android Studio,基础配置涉及 APP 名称修改、接口域名更换、包名调整及第三方登录分享(如 QQ、微信)的配置,同时需完成阿里云与腾讯云相关设置。
|
9月前
|
XML JavaScript Android开发
【Android】网络技术知识总结之WebView,HttpURLConnection,OKHttp,XML的pull解析方式
本文总结了Android中几种常用的网络技术,包括WebView、HttpURLConnection、OKHttp和XML的Pull解析方式。每种技术都有其独特的特点和适用场景。理解并熟练运用这些技术,可以帮助开发者构建高效、可靠的网络应用程序。通过示例代码和详细解释,本文为开发者提供了实用的参考和指导。
301 15
|
9月前
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
|
存储 Linux API
深入探索Android系统架构:从内核到应用层的全面解析
本文旨在为读者提供一份详尽的Android系统架构分析,从底层的Linux内核到顶层的应用程序框架。我们将探讨Android系统的模块化设计、各层之间的交互机制以及它们如何共同协作以支持丰富多样的应用生态。通过本篇文章,开发者和爱好者可以更深入理解Android平台的工作原理,从而优化开发流程和提升应用性能。
|
Web App开发 JavaScript 前端开发
Android中WebView加载本地Html,与JavaScript与Android方法相互传值(续)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010046908/article/details/51809558 ...
1149 0
|
2月前
|
移动开发 前端开发 Android开发
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
269 12
【02】建立各项目录和页面标准化产品-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
2月前
|
移动开发 JavaScript 应用服务中间件
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
226 5
【06】优化完善落地页样式内容-精度优化-vue加vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
2月前
|
移动开发 Rust JavaScript
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
562 4
【01】首页建立-vue+vite开发实战-做一个非常漂亮的APP下载落地页-支持PC和H5自适应提供安卓苹果鸿蒙下载和网页端访问-优雅草卓伊凡
|
3月前
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
513 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡

推荐镜像

更多