Android AsyncTask 深度解析

Android并发编程三剑客:Thread、AsyncTask与IntentService深度解析 本文对比了Android开发中三种常用并发编程工具:Thread、AsyncTask和IntentService。Thread作为基础并发单元,提供完全手动控制的灵活性,适合复杂并发场景但需谨慎管理生命周期。AsyncTask封装了线程池和Handler机制,简化UI线程交互,适合轻量级后台任务和UI更新。IntentService结合Service可靠性和HandlerThread便利性,提供顺序执行的后台任务处理能力,适合长时间运行的操作。 阅读详情

Android 中耗时操作是在子线程中完成的,子线程不能更新UI,于是便出现了大家熟悉的异步消息处理机制Handler,Handler把在子线程中创建的Message对象发送到消息队列中,经由Looper轮询取出再交由Handler中handleMessage()方法处理。Handler机制完美解决了子线程中有数据却不能更新UI的问题,但是创建Handler对象、重写handleMessage()方法处理消息、创建子线程并创建Message对象显然有些复杂,为了代码更加简单、使用更加方便Android在API 3 推出了AsyncTask这一更简单、好用的异步操作工具。

其实AsyncTask使用的仍然是Handler机制,其内部封装了一个Handler的子类对象InternalHandler对象,关于源码部分后面介绍,下面介绍AsyncTask的使用:

AsyncTask是一个抽象类,其直接父类是Object,我们可以自定义一个类继承AsyncTask,重写其内部的抽象方法doInBackground(Params ... params);

AsyncTask 这个类有三个泛型限定,AsyncTask<Params ,Progress ,Result> 接下来会介绍到它们的作用。

AsyncTask之方法解析一:doInBackground(Params ... params)

1.在onPreExecute()方法执行结束之后该方法会被自动调用;

2.该方法在子线程中执行,通常做一些耗时操作;

3.该方法中的可变参数params是由AsyncTask子类对象调用execute(Params ... params)方法时传递而来,该参数的类型由AsyncTask类上的第一个泛型限定;

4.该方法的返回值将会传递给onPostExecute(Result ... result)方法作为参数使用,返回值类型由AsyncTask类上的第三个泛型限定;

5.在该方法中可以调用publishProgress(Progress ... progress)发布任务完成的进度,该进度值progress将会被发布到主线程onUpdateProgress(Progress ... progress)方法中,作为该方法的参数使用。

AsyncTask之方法解析二:onPreExecute()

1.该方法在主线程中执行;

2.该方法在任务开始前执行,通常用来初始化任务,比如向用户展示一个进度条。

AsyncTask之方法解析三:onPostExecute(Result ... result)

1.该方法在主线程中执行;

2.该方法在耗时操作完成后执行,即在doInBackground(Params ... params)方法结束后执行;

3.该方法的参数result是耗时操作返回的结果,即doInBackground(Params ... params)返回的结果,参数类型由AsyncTask类上的第三个泛型限定;

AsyncTask之方法解析四:onProgressUpdate(Progress ... progress)

1.该方法在主线程中执行;

2.该方法在publishProgress(Progress... progress)每次调用后执行,通常用来向用户展示耗时操作的进度;

3.该方法的参数progress是耗时操作的进度,由publishProgress(Progress ... progress)传递而来,参数类型由AsyncTask类上的第二个泛型限定;

了解完以上方法之后,我们就可以开始写个小demo测试一下啦!

public class MainActivity extends AppCompatActivity {
    public static final String TAG = "MainActivity";
    private MainActivity context;
    private ProgressDialog mDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = MainActivity.this;
        MyAsyncTask task = new MyAsyncTask();
        task.execute(10);//对应类中第一个泛型Integer
    }

    /**
     * 求和异步任务
     */
    class MyAsyncTask extends AsyncTask<Integer, Integer, Long> {

        /**
         * 初始化任务,展示进度条,在主线程
         */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.d(TAG, "--- onPreExecute --- " + Thread.currentThread().getName());
            mDialog = new ProgressDialog(context);//创建一个进度对话框
            mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            mDialog.show();
        }

        /**
         * 在子线程执行耗时操作,通过publishProgress(Progress ... progress)方法将任务执行的进度传出
         * @param params 该参数由task.execute(10);传递而来
         * @return
         */
        @Override
        protected Long doInBackground(Integer... params) {
            long sum = 0;
            for (int i = 1; i < params[0]; i++) {
                sum += i;
                publishProgress(params[0], i);//发布进度,参数将传递到onProgressUpdate方法中
                try {
                    Thread.sleep(1000);
                    Log.d(TAG, "--- doInBackground --- " + Thread.currentThread().getName() + "  i == " + i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return sum;
        }

        /**
         * 执行在主线程,向用户展示任务的进度
         *
         * @param values 该参数由publishProgress(Progress ... progress)传递而来
         */
        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            mDialog.setMax(values[0]);
            mDialog.setProgress(values[1]);
        }

        /**
         * 执行在主线程,任务执行完成后的操作,隐藏进度条等
         *
         * @param aLong 该参数由doInBackground()返回
         */
        @Override
        protected void onPostExecute(Long aLong) {
            super.onPostExecute(aLong);
            //返回操作结果 , 进度对话框消失
            mDialog.dismiss();
            Log.d(TAG, "--- onPostExecute --- " + Thread.currentThread().getName() + "  aLong == " + aLong);
        }
    }
}

这个小demo通过求1-10的和,在doInBackground()方法中通过延时的方式模拟了耗时操作,简单的演示了AsyncTask的使用。
Log日志如下:

02-17 09:40:32.214 8207-8207/com.qj.asynctasktest D/MainActivity: --- onPreExecute --- main
02-17 09:40:33.270 8207-8246/com.qj.asynctasktest D/MainActivity: --- doInBackground --- AsyncTask #1  i == 1
02-17 09:40:34.273 8207-8246/com.qj.asynctasktest D/MainActivity: --- doInBackground --- AsyncTask #1  i == 2
02-17 09:40:35.277 8207-8246/com.qj.asynctasktest D/MainActivity: --- doInBackground --- AsyncTask #1  i == 3
02-17 09:40:36.279 8207-8246/com.qj.asynctasktest D/MainActivity: --- doInBackground --- AsyncTask #1  i == 4
02-17 09:40:37.280 8207-8246/com.qj.asynctasktest D/MainActivity: --- doInBackground --- AsyncTask #1  i == 5
02-17 09:40:38.281 8207-8246/com.qj.asynctasktest D/MainActivity: --- doInBackground --- AsyncTask #1  i == 6
02-17 09:40:39.282 8207-8246/com.qj.asynctasktest D/MainActivity: --- doInBackground --- AsyncTask #1  i == 7
02-17 09:40:40.284 8207-8246/com.qj.asynctasktest D/MainActivity: --- doInBackground --- AsyncTask #1  i == 8
02-17 09:40:41.286 8207-8246/com.qj.asynctasktest D/MainActivity: --- doInBackground --- AsyncTask #1  i == 9
02-17 09:40:42.288 8207-8246/com.qj.asynctasktest D/MainActivity: --- doInBackground --- AsyncTask #1  i == 10
02-17 09:40:42.310 8207-8207/com.qj.asynctasktest D/MainActivity: --- onPostExecute --- main  aLong == 55

由Log可看出:

onPreExecute()和onPostExecute()方法都执行在主线程,onProgressUpdate()能够更改UI(更改进度条进度)必然也是主线程。

doInBackground()方法执行在线程池某一线程中,(看过源码后得到的结果,通过Log可以知道该方法没有执行在主线程中)

AsyncTaskTest源码下载

AsyncTask使用中的注意事项:

1. AsyncTask实例对象必须在UI线程中创建;

2. execute()方法必须在UI线程中调用;

3. 不要手动调用onPreExecute()、doInbackground()、onProgressUpdate()、onPostExecute()这四个方法;

4. 同一个task任务只能被执行一次,尝试执行第二次会抛出异常;

5. execute()执行任务默认是串行的,(API 11之后)多个AsyncTask任务是顺序执行的,如果想并行可以用executeOnExecutor()方法。AsyncTask中为我们提供了一个并行的线程池THREAD_POOL_EXECUTOR。

 

GEE开发之Landsat8计算MNDWI和数据分析 上一篇博客介绍了landsat8计算NDWI以及数据的获取,这次介绍MNDWI(改进的归一化差异水体指数)。 阅读详情

相关推荐

从亚稳态到稳定传输:深入解析CDC跨时钟域同步的核心技术与设计实践

本文深入解析了CDC(跨时钟域同步)技术的核心问题与解决方案,重点探讨了亚稳态现象及其危害,详细介绍了同步器设计、MTBF计算方法以及单bit和多bit信号同步的实战技巧。通过Verilog代码示例和工程实践案例,帮助读者掌握从亚稳态到稳定传输的关键技术,提升数字电路设计的可靠性。

weixin_32822843的博客 246

Android AsyncTask(线程间通信)

1.AsyncTask 在Android中我们可以通过Thread+Handler实现多线程通信,一种经典的使用场景是:在新线程中进行耗时操作,当任务完成后通过Handler向主线程发送Message,这样主线程的Handler在收到该Message之后就可以进行更新UI的操作。上述场景中需要分别在Thread和Handler中编写代码逻辑,为了使得代码更加统一,我们可以使用AsyncTask类。 AsyncTask是Android提供的一个助手类,它对Thread和Handler进行了封装,方便我们使用。

zenmela2011的专栏 6742

紫光同创PGL50H开发板实战:盘古50KH视频板的多媒体处理与高速通信方案

本文详细介绍了基于紫光同创PGL50H FPGA芯片的盘古50KH视频开发板在多媒体处理与高速通信方面的实战应用。文章从开发板硬件架构解析入手,逐步指导开发环境搭建、DDR3内存控制器配置、HDMI视频输入输出实战,并重点探讨了利用板载HSST高速收发器实现光纤通信与万兆以太网的方案。最后,通过构建一个集多路视频采集、处理与光纤传输于一体的系统案例,展示了该开发板在高性能实时数据处理领域的强大潜力。

b9c0d的博客 484

2016级移动应用开发在线测试11-线程

有趣有内涵的文章第一时间送达!  喝酒I创作I分享 生活中总有些东西值得分享 @醉翁猫咪  1. 下面关于多线程技术描述错误的是()   您的回答为:线程是进程的一个实体,是CPU调度和分派的基本单位。一个进程可以启动多个线程。线程不能够独立运行,总是属于某个进程,进程中的多个线程共享进程的内存。一个线程可以创建和撤销另一个

程序员哆啦A梦,蓝胖子 605

MediaPipe实战:从零构建人脸关键点检测应用

本文详细介绍了如何使用Google的MediaPipe框架从零构建一个实时人脸关键点检测应用。文章深入剖析了MediaPipe的三段式检测流水线,提供了Android平台的完整实战教程,包括环境配置、模型加载、摄像头集成、关键点绘制以及性能调优指南,帮助开发者快速实现高效、跨平台的人脸AR特效与交互功能。

weixin_29100927的博客 339

MIC卡的OFED驱动安装

 IB网络和OFED驱动安装 IB InfiniBand是一个统一的互联结构,可以处理存储I/O、网络I/O和进程间通信(IPC)。它可以将磁盘阵列、SANs、LANs、服务器和集群服务器进行互联,也可以连接外部网络(比如WAN、VPN、互联网)。设计InfiniBand的目的主要是用于企业数据中心,大型的或小型的。目标主要是实现高的可靠性、可用性、可扩展性和高的性能。Inf

beglorious的专栏 5105

AsyncTask异步任务解析

AsyncTask用于处理异步加载问题AsyncTask的基本用法由于AsyncTask是一个抽象类,所以如果我们想使用它,就必须要创建一个子类去继承它。在继承时我们可以为AsyncTask类指定三个泛型参数。如:class MyAsncTask extends AsyncTask<Void, Integer, Boolean> { …… }执行Aynctask时需要传入的参数类型,可用于在

csdnhyp的博客 546

PL/SQL 中的数据导入和导出:CSV 文件格式详解

在 PL/SQL 开发中,数据的导入和导出是常见的操作。本文将深入探讨如何使用 PL/SQL 导入和导出 CSV 文件格式的数据,帮助你轻松地实现数据迁移、备份和数据交换等需求。CSV(Comma-Separated Values)是一种常见的文本文件格式,它以逗号作为字段的分隔符,每行表示一个记录。使用 CSV 格式可以方便地在不同的系统之间共享和传输数据。下面我们将分步介绍如何在 PL/SQL 中导入和导出 CSV 文件格式的数据。

pleaseprintf的博客 8835

Android AsyncTask的doInBackground不执行问题

今天在写一个小程序的时候,遇到一个问题:一个activity页面的AsyncTask的doInBackground不执行。试着在doInBackground里面打印了下log,确认是走不到doInBackground里面: @Override protected Result<JokeInfo> doInBackground(Integer... params) {

A WAY 3048

全志A527 T527 android13支持usb摄像头

我们发现usb摄像头在A527 android13上面并不能正常使用,需要支持相关的摄像头。

zhutoubenben的专栏 964

西门子S7-1200PLC控制步进电机的组态编程和具体步骤

西门子S7-1200PLC控制步进电机的组态编程和具体步骤 硬件准备: 1) 一个S7-1214C DC/DC/DC,订货号:6ES7 214-1AG40-0XB0 2) 一个86系的步进电机+相应的驱动器 3) 一个20A的西门子24V电源(步进驱动器及plc电源) 4) Portal V15版本 组态及编程: 1) 创建一个验证项目,添加cpu( S7-1214C),双击“工艺对象”,选择“运动控制”的TO_PositioningAxis V6.0版本,如下图所示: 2) “确定”后,系统自动生成名

Robot_PLC_HMI_Automation 1万+

深入解析AsyncTask(doInBackground不工作)

近日开发遇到AsyncTask的doInBackground()方法不执行的问题,所以在网上查找原因,以下博文解决了我的问题,我用Thread代替了AysncTask进行工作。博文如下: http://blog.youkuaiyun.com/gf771115/article/details/17248037 以前是这样写的,总是执行不到doInBackground: mYuyinCloudR

zhengxiangwen的专栏 922

AI大模型:(三)3.2 Spring AI实现Agent

SpringAI实现了流式对话功能,通过与Ollama模型集成完成前后端交互,当前版本存在thinking信息丢失问题。系统支持两种工具注册方式(方法注解和函数式),并内置时间工具类展示外部工具调用能力。记忆功能提供多种存储方案(内存、JDBC、NoSQL等),实现跨对话轮次的上下文保持。MCP协议集成方面,服务端实现计算和业务查询工具,客户端支持12306及自定义业务系统接入。完整演示了流式对话、工具调用与记忆功能的综合应用。该实践构建了具备复杂交互能力的AI系统,同时指出生产环境需关注的安全与优化问题。

haylee的专栏 1007

Android AsyncTask 深度解析,mic面试宝典

首先是感觉自己的基础还是不够吧,大厂好像都喜欢问这些底层原理。之前的准备只涉及了Java、Android、计网、数据结构与算法这些方面,面对面试官对其他基础课程的考察显得捉襟见肘。下一步还是要查漏补缺,进行针对性复习。最后的最后,那套资料这次一定要全部看完,是真的太全面了,各个知识点都涵盖了,几乎我面试遇到的所有问题的知识点这里面都有!希望大家不要犯和我一样的错误呀!!!一定要看完!网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

2401_84481029的博客 780

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Android AsyncTask 深度解析,面试必会

MyAsyncTask task = new MyAsyncTask(); task.execute(10);//对应类中第一个泛型Integer } /** 求和异步任务 */ class MyAsyncTask extends AsyncTask<Integer, Integer, Long> { /** 初始化任务,展示进度条,在主线程 */ @Override protected void onPreExecute() { super.onPreExecute(); Log.d(

wq221aas的博客 184

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Android AsyncTask 深度解析,移动端混合开发

1.该方法在主线程中执行; 2.该方法在耗时操作完成后执行,即在doInBackground(Params … params)方法结束后执行; 3.该方法的参数result是耗时操作返回的结果,即doInBackground(Params … params)返回的结果,参数类型由AsyncTask类上的第三个泛型限定; AsyncTask之方法解析四:onProgressUpdate(Progress … progress) 1.该方法在主线程中执行; 2.该方法在publishProgress(Progr

m0_64603776的博客 530

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Android AsyncTask 深度解析,2021年最新Android面试经历

AsyncTask之方法解析一:doInBackground(Params … params) 1.在onPreExecute()方法执行结束之后该方法会被自动调用; 2.该方法在子线程中执行,通常做一些耗时操作; 3.该方法中的可变参数params是由AsyncTask子类对象调用execute(Params … params)方法时传递而来,该参数的类型由AsyncTask类上的第一个泛型限定; 4.该方法的返回值将会传递给onPostExecute(Result … result)方法作为参数使用,返

m0_66144910的博客 134

Android AsyncTask 深度解析,给后辈的一点建议

***/@Override//创建一个进度对话框/**在子线程执行耗时操作,通过publishProgress(Progress … progress)方法将任务执行的进度传出@param params 该参数由task.execute(10);传递而来@return*/@Overridei++) {sum += i;//发布进度,参数将传递到onProgressUpdate方法中try {return sum;/**执行在主线程,向用户展示任务的进度。

576

反杀套路!阿里独家的《Android 开发相关源码精编解析,基于web的系统设计

由于篇幅问题,就不全部展示了。需要的评论【666】,点击即可获得!

2401_84182073的博客 776

Android AsyncTask完全解析FutureTask 深度解析 -Java并发编程:Callable、Future和FutureTask一个使用DownloadManager下载文件的小例

作者:韩梦飞沙 QQ:313134555 Android AsyncTask完全解析,带你从源码的角度彻底理解 - 。。。 - 博客频道 - youkuaiyun.comAndroid 中文 API (101) —— AsyncTask - 农民伯伯 - 博客园 FutureTask 深度解析 - liulipuo的专栏 - 博客频道 - youkuaiyun.comJava并发编程:Cal

韩梦飞沙_韩亚飞 451

Android Snackbar 带操作按钮实战:cw-omnibus SnackbarAction 示例深度解析

本篇技术指南基于 cw-omnibus 仓库中的 Design Support Library 示例项目 [SnackbarAction](https://link.gitcode.com/i/d1aa35ba39b0901e0456f512a62bf9d1),讲解如何在 Android 应用中使用 `Snackbar` 向用户展示短暂提示,并通过 `setAction()` 为其附加一个可点击的

gitblog_01042的博客 755

Android 网络操作实战:使用 XmlPullParser 解析 XML 数据(android-training-course-in-chinese)

XML(Extensible Markup Language)是把文档编码为机器可读形式的标准规则集,也是网络上共享数据的普遍格式——新闻网站、博客等频繁更新内容的站点,通常都会提供 XML 提要(XML feed)让外部程序跟进内容变化,因此"下载并解析 XML 数据"是几乎所有网络类 Android 应用都要面对的常见需求。本篇以《Android官方培训课程中文版》(android-train

gitblog_00438的博客 712
上一篇: Android获取App当前页面的Activity名称
下一篇: Android正方形View
github_2011
博客等级 码龄10年 116粉丝 56原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值