Android中的AsyncTask

近期写了一个项目,在前台刷新界面的时候需要操作数据库,进行数据操作,在UI线程更新数据会导致ANR,程序十分卡,因此用了AsyncTask进行后台数据处理。

介绍

AsyncTask是一个用于在后台线程执行异步任务并在主线程更新UI的类。它是在Android API Level 3中引入的,并被广泛使用。

下面是一个简单的AsyncTask的示例:

public class MyTask extends AsyncTask<Void, Void, String> {

    @Override
    protected String doInBackground(Void... params) {
        // 后台执行耗时操作
        return "result";
    }

    @Override
    protected void onPostExecute(String result) {
        // 在UI线程更新UI
    }
}

AsyncTask定义了三个泛型参数:

  • Params:指定异步任务执行时传入的参数类型。
  • Progress:指定异步任务执行过程中用于更新UI的进度的类型。
  • Result:指定异步任务执行完成后返回的结果类型。

在上面的示例中,ParamsVoid,即没有传入参数,ProgressVoid,即没有进度更新,ResultString,即返回一个字符串结果。

基本结构

AsyncTask是一个抽象类,它的实现需要通过继承它并实现其抽象方法来完成。它的定义如下:

public abstract class AsyncTask<Params, Progress, Result> {
    // ...
}

其中,ParamsProgressResult是泛型参数,分别对应异步任务执行时传入的参数类型、进度更新的类型和返回的结果类型。

AsyncTask定义了一些静态常量,如SERIAL_EXECUTORTHREAD_POOL_EXECUTORDEFAULT_EXECUTOR等。这些常量表示了AsyncTask可以使用的线程池类型,其中SERIAL_EXECUTOR是一个串行线程池,THREAD_POOL_EXECUTOR是一个固定大小的线程池,DEFAULT_EXECUTOR是默认的线程池。

执行流程

AsyncTask的执行流程可以分为以下几个阶段:

  1. onPreExecute():在UI线程中执行,用于在异步任务执行前进行一些准备工作,例如显示进度条等。
  2. doInBackground(Params...):在后台线程中执行,用于执行耗时操作,不可以更新UI。
  3. onProgressUpdate(Progress...):在UI线程中执行,用于更新进度,例如更新进度条等。
  4. onPostExecute(Result):在UI线程中执行,用于执行异步任务完成后的操作,例如更新UI等。
  5. onCancelled():在UI线程中执行,用于在异步任务被取消时执行的操作。

应用

创建一个类继承AsyncTask

 private class DealDataColor extends AsyncTask {

        @Override
        protected Object doInBackground(Object[] objects) {
           //进行数据处理
            return null;
        }
    }

在主线程调用execute方法更新UI

 DealDataColor dealDataColor = new DealDataColor();
 dealDataColor.execute();

源码分析

这里使用的时候会发现,创建后的AsyncTask在execute后就不能再次使用了,那么为什么会这样设计呢?

看看源码:

//这是execute方法的实现
   public final AsyncTask<Params, Progress, Result> execute(Params... params) {
        return executeOnExecutor(sDefaultExecutor, params);
    }



//在execute里调用了executeOnExecutor
    public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
            Params... params) {
        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;

        onPreExecute();

        mWorker.mParams = params;
        exec.execute(mFuture);

        return this;
    }

可以看到这里先判断mStatus的值,这个值是一个枚举类里的值

    public enum Status {
        /**
         * Indicates that the task has not been executed yet.
         */
        PENDING,
        /**
         * Indicates that the task is running.
         */
        RUNNING,
        /**
         * Indicates that {@link AsyncTask#onPostExecute} has finished.
         */
        FINISHED,
    }


  private volatile Status mStatus = Status.PENDING;

这个值在初始化刚进来的时候已经被赋予了PENDING,判断值如果是不是PENDING直接就会抛出异常。

execute()executeOnExecutor() 方法的区别在于:

 

execute是固定了线程池执行。里面传入的sDefaultExecutor 是静态的

private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;

executeOnExecutor里面可以自定义线程池。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/11942.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

set/multiset容器

1、set/multiset容器简介 但是 set 容器只有键值&#xff0c;在插入数据的时候会自动根据 键值 进行排序&#xff0c;所以不允许有相同的键值存在&#xff0c;也不能修改 set 容器元素值&#xff0c;会破坏 set 的数据结构。set 容器的迭代器是只读迭代器 2、set容器 API 操作…

读懂AUTOSAR :DiagnosticLogAndTrace DLT(四)-- API解析

一、周期调用的函数&#xff1a;Dlt_TxFunction 根据参数DltGeneralTrafficShapingSupport&#xff0c;决定如何去发送DLT消息。如果为TRUE&#xff0c;那需要参考参数DltLogChannelTrafficShapingBandwidth为每个Log通道设置发送带宽&#xff1b;如果为FALSE&#xff0c;那么…

纯虚函数和抽象类

什么时候使用纯虚函数: 某些类,在现实角度和项目实现角度,都不需要实例化(不需要创建它的对象),这个类中定义的某些成员函数,只是为了提供一个形式上的借口,准备让子类来做具体化的实现,此时,这个方法就可以定义为"纯虚函数",包含纯虚函数的类,就称为抽象类. 纯虚函…

Java入坑之集合、流与序列化

一、集合 1.1集合定义 集合概念&#xff1a; 保存和盛装数据的容器&#xff0c;将许多元素组合成一个单一单元的容器对象。集合&#xff0c;可用于存储/检索/操作/传输/聚合数据集合框架&#xff1a; 表示和操作集合的体系&#xff0c;包括接口、实现类&#xff0c;集合框架的…

python真的如此好吗?

作为一名合格的&#xff08;准&#xff09;程序员&#xff0c;必做的一件事是关注编程语言的热度&#xff0c;编程榜代表了编程语言的市场占比变化&#xff0c;它的变化更预示着未来的科技风向和机会&#xff01; Python霸占榜首 只因它真的很强 Python&#xff0c;年龄可能比…

这篇文章价值很大:股票历史分时成交数据怎么简单获取?【干货】

文章目录前言一、准备二、使用步骤1.引入库2&#xff0c;使用这个API查询历史分时数据&#xff1a;3.查询完整历史分时数据4.其他查询方法参数格式&#xff1a;[(市场代码, 股票代码), ...]参数&#xff1a;市场代码, 股票代码, 文件名, 起始位置, 数量参数&#xff1a;市场代码…

MySQL-binlog+dump备份还原

目录 &#x1f341;binlog日志恢复 &#x1f342;binlog介绍 &#x1f342;Binlog的用途 &#x1f342;开启binary log功能 &#x1f342;配置binlog &#x1f341;mysqldump &#x1f342;数据库的导出 &#x1f342;数据库的导入 &#x1f341;mysqldumpbinlog &#x1f990;…

【Python_Scrapy学习笔记(一)】Scrapy框架简介

Scrapy框架简介 前言 Scrapy 框架是一个用 python 实现的为了爬取网站数据、提取数据的应用框架&#xff0c;使用 Twisted 异步网络库来处理网络通讯&#xff0c;可以高效的完成数据爬取。本文主要介绍 Scrapy 框架的构成与工作原理。 正文 1、Scrapy安装 Windows安装&…

引导程序、BIOS中断、检测内存容量、实模式切换到保护模式

初始化引导程序 基本概念 BIOS会将磁盘的第0个扇区(大小为512字节)&#xff0c;加载到0x7c00处。 引导程序负责操作系统的加载&#xff0c;主要用于为操作系统运行提供初始化环境&#xff0c;并运行加载操作系统。 BIOS只加载磁盘的第0个扇区(512字节)到内存中&#xff0c;次程…

笔记本电脑开不了机?3种解决方法

案例&#xff1a;笔记本电脑开不了机怎么办&#xff1f; 【我的笔记本电脑一直用得好好的&#xff0c;今天突然开不了机&#xff0c;尝试按了开机键很多次也没有解决。有人遇到过同样的问题吗&#xff1f;有没有解决的方法&#xff01;】 在日常生活中&#xff0c;我们经常会…

【计算机网络——计算机网络的概念,组成,功能和分类以及相关的性能指标,分层结构和协议,TCP/IP参考模型】

文章目录计算机网络体系结构计算机网络的概念、组成、功能和分类标准化工作及相关组织速率相关的性能指标时延、时延带宽积、PTT和利用率分层结构、协议、接口和服务OSI参考模型TCP IP参考模型计算机网络体系结构 计算机网络的概念、组成、功能和分类 计算机网络的概念 计算…

游戏内嵌社区服务开放,助力开发者提升玩家互动与留存

华为 HMS Core 游戏内嵌社区服务提供快速访问华为游戏中心论坛能力&#xff0c;支持玩家直接在游戏内浏览帖子和交流互动&#xff0c;助力开发者扩展内容生产和触达的场景。 一、为什么要游戏内嵌社区&#xff1f; 二、游戏内嵌社区的典型使用场景 1、游戏内打开论坛 您可以在…

【从零开始学Skynet】实战篇《球球大作战》(十三):场景代码设计(下)

1、主循环 《球球大作战》是一款服务端运算的游戏&#xff0c;一般会使用主循环程序结构&#xff0c;让服务端处理战斗逻辑。如下图所示&#xff0c;图中的balls和foods代表服务端的状态&#xff0c;在循环中执行“食物生成”“位置更新”和“碰撞检 测”等功能&#xff0c;从而…

商城系统开发方案分析

互联网的不断发展&#xff0c;电商行业已经成为了当前最重要的商业形式之一。商城系统的开发也因此而备受关注。商城系统的开发是针对B2C、B2B2C等多种商业模式&#xff0c;如用户熟知的SHOP、商派等一系列商城系统&#xff0c;将商品和服务进行在线销售的一个综合性平台。那么…

【C语言进阶:动态内存管理】常见的动态内存错误

本节重点内容&#xff1a; 对NULL指针的解引用操作对动态开辟空间的越界访问对非动态开辟内存使用free释放使用free释放一块动态开辟内存的一部分对同一块动态内存多次释放动态开辟内存忘记释放&#xff08;内存泄漏&#xff09;经典的笔试题⚡对NULL指针的解引用操作 ⚡对动态…

Linux基础命令-seq打印数字序列

Linux基础命令-sed流编辑器 前言 seq命令通常是用来打印一串有规律的数字&#xff0c;常与其他命令搭配使用&#xff0c;一起来看下它的用法。 一. 命令介绍 在doc文档中查看seq命令的含义 NAMEseq - print a sequence of numbers DESCRIPTIONPrint numbers from FIRST to…

李宏毅教程系列——增强学习

目录 0. 强化学习wiki 1. 介绍 2. Exploration vs Exploitation 探索与开发 3. 各类最优化方法 3.1 Brute force猛兽蛮力法&#xff08;暴力搜索&#xff09; 3.2 Value function estimation&#xff08;价值函数估计&#xff09; 3.2.1 Monte Carlo methods 蒙特卡洛方…

3年经验,面试测试岗只会功能测试开口要求18K,令我陷入沉思。

由于朋友临时有事&#xff0c; 所以今天我代替朋友进行一次面试&#xff0c;公司需要招聘一位自动化测试工程师&#xff0c;我以很认真负责的态度完成这个过程&#xff0c; 大概近30分钟。 主要是技术面试&#xff0c; 在近30分钟内&#xff0c; 我与被面试者是以交流学习的方式…

【Linux】通过网络版计算器来认识协议

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;再谈协议&…

腾讯云4核8G12M轻量服务器配置性能评测

腾讯云轻量4核8G12M服务器&#xff0c;之前是4核8G10M配置&#xff0c;现在公网带宽和月流量包整体升级&#xff0c;12M公网带宽下载速度可达1536KB/秒&#xff0c;系统盘为180GB SSD盘&#xff0c;每月2000GB免费流量&#xff0c;腾讯云百科来详细说下4核8G12M轻量应用服务器配…