11 |「异步任务与多线程」

前言

实践是最好的学习方式,技术也如此。

文章目录

    • 前言
    • 一、同步和异步的概念
      • 1、同步和异步任务
      • 2、线程
    • 二、Android 多线程与 Handler 机制
      • 1、分类
      • 2、原则
      • 3、Handler 机制
        • 1)问题(背景)
        • 2)Handler 异步通信系统
        • 3)消息传递流程
    • 三、代码举例

一、同步和异步的概念

1、同步和异步任务

  • 同步任务
    • 在执行程序时,如果一直没有收到执行结果,就一直等待,不继续往下执行,直到收到执行结果,才接着往下执行;
  • 异步任务
    • 在执行程序时,如果遇到需要等待的任务,就另外开辟一个子线程去执行它,自己继续往下执行其他程序。子线程有结果时,会将结果发送给主线程。异步任务的形式不影响程序的主要进程。

2、线程

  • 是什么
    • 就是一个执行过程,多线程即多个执行过程;
  • 为什么要有多线程
    • 程序中可能有多个任务,如果只有一个线程,那么就只能一个接着一个执行,就类似于同步执行任务,明显执行结果会比较慢,因为只有上一个任务执行完成,才能进行下一个。因此,需要多个线程来分别执行这些任务,即对应了上面的异步任务。

二、Android 多线程与 Handler 机制

1、分类

  • 主线程

    • 对于 Android App 程序。App 一启动,本身就是一个线程,这个线程被称为 主线程(main Thread);
    • 负责显示界面与用户进行实时交互(例如,用户点击一个按钮、输入文字,都需要程序进行响应处理);因为界面通常被称为 UI,所以,主线程又被称为 UI 线程。
  • 子线程

    • 除了主线程,剩下开辟的线程都称为子线程;
  • 类比生活中的例子

    • 场景:小明宴请客人
      • 主线程:小明;
      • 响应用户对界面的操作:小明接待客人;
      • 耗时操作:做饭;
      • 开启子线程:请一个保姆来做饭;

2、原则

  • 主线程不能执行网络请求/文件读写等耗时操作,就不能实时响应界面;
  • 子线程不能执行 UI 刷新(不能操作 UI 元素,操作任何一个控件);
  • 总结
    • 当遇到比较耗时的任务时,主线程可以开启一个子线程去执行,主线程接着执行主界面的响应任务,不影响用户的交互感受;类比,小明接待客人,请一个保姆去做饭,自己继续接待客人,不影响客人的感受;
    • 子线程不能更新 UI 界面,就像是保姆不能直接接待客人一样,对用户是不可见的;

3、Handler 机制

1)问题(背景)
  • 主线程中开启子线程,子线程执行任务完成将结果传递给主线程;子线程如何将结果(数据)传递给主线程,来实现主线程进行界面的改变?
2)Handler 异步通信系统
  • Handler 的英文名词解释:处理者;
  • 主要角色:程序员只需要了解 HandlerMessage 这两个角色即可,剩下两个角色都是安卓系统在底层已经封装好的;
    • Handler:类的名字;
    • Message:消息
      • 子线程执行任务完成将结果传递给主线程,传递的就是这个 Message 实体的对象;
    • MessageQueue:消息队列
    • Looper
      • 承担了主线程不时地查看邮箱中是否有消息的角色;
      • 从消息队列中拿消息,只要消息队列中有消息,就会一直不停的拿;
3)消息传递流程
  • 主线程在建立的时候就建立了上图所示的一套 Handler 系统,建立的过程是在底层进行的;
  • 子线程要传递给主线程消息,需要通过 Handler
    • 子线程会先拿到主线程的 Handler

    • Handler 通过sendMessage() 方法发送消息,消息发送至消息队列中(而不是直接发送给主线程);

      • 为什么不直接将消息发送给主线程?(时机的问题)
    • Looper 从消息队列中拿消息,将拿到的消息回传给 HandlerHandler 收到回传回来的消息之后就会执行 handlerMessage 方法(处理消息的方法);

  • 总结
    • 主线程的 Handler 系统进行消息流转;
    • 主线程会从系统中的消息队列中拿到消息交给自己,然后调用 HandleMessage 方法,就可以收到子线程传给主线程的消息了;

三、代码举例

  • 代码背景描述:选择选项框中对应城市的 item 实现查找对应城市的天气数据;
// 初始化
private void initView() {mSpinner = findViewById(R.id.sp_city);/*** 设置Adapter* 获取数据* 将自定义布局、数据与Adapter进行关联* 设置Spinner的Adapter*/mCities = getResources().getStringArray(R.array.cities);mSpAdapter = new ArrayAdapter<>(this, R.layout.sp_item_layout, mCities);mSpinner.setAdapter(mSpAdapter);mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {// 当Spinner中选中某一项时被调用@Overridepublic void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {// 选中城市后,会拿到选中城市名字,根据拿到的城市名字来查询对应城市的天气String selectCity = mCities[i];getWeatherCity(selectCity);  // 开启子线程}// 当Spinner没有选中任何项时被调用@Overridepublic void onNothingSelected(AdapterView<?> adapterView) {}});tvWeather = findViewById(R.id.tv_weather);tvAir = findViewById(R.id.air);tvTem = findViewById(R.id.tv_tem);tvTemLowHigh = findViewById(R.id.tv_tem_low_high);tvWin = findViewById(R.id.tv_win);ivWeather = findViewById(R.id.iv_weather);rlvFutyreWeather = findViewById(R.id.rlv_future_weather);
}
// 请求网络(开启一个子线程)
private void getWeatherCity(String selectCity) {// 开启子线程,请求网络new Thread(new Runnable() {@Overridepublic void run() {// 请求网络,拿到天气数据String weatherOfCity = NetUtil.getWeatherCity(selectCity);// 使用Handler将数据传递给主线程Message message = Message.obtain();  // 效率高,从消息池里拿消息,利于对象的重用message.what = 0;  // 标识哪个消息message.obj = weatherOfCity;  // 将数据放到消息中mHandler.sendMessage(message);  // 将消息发出去}}).start();
}
// 主线程处理子线程发送来的消息
private Handler mHandler = new Handler(Looper.myLooper()) {// 重写里面的方法 ctrl+o// 重写handleMessage方法@Overridepublic void handleMessage(@NonNull Message msg) {  // 接收handler发出的消息super.handleMessage(msg);if (msg.what == 0) {// 在主线程中拿到消息String weather = (String) msg.obj;Log.d("fan", "---主线程收到了天气数据---" + weather);// 解析JSONGson gson = new Gson();// 将JSON格式复杂的字符串解析成Java对象WeatherBean weatherBean = gson.fromJson(weather, WeatherBean.class);Log.d("fan", "---解析后的数据---" + weatherBean.toString());updateUiOfWeather(weatherBean);}}
};
  • 明确:主线程和子线程执行代码的顺序和代码的所属范围;
    • 子线程拿到主线程的 Handler,因为 Handler 本身属于是主线程的,所以处理消息(handlerMessage)也是在主线程中(属于主线程范围)
  • 红色箭头为主线程执行的代码,黄色框里的为子线程执行的代码范围,两者互不干涉,只执行自己范围内的代码,不能执行范围外的代码;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

重塑生产格局:新质生产力引领下的新型工业操作系统和工业母机创新动向

新质生产力是创新起主导作用&#xff0c;摆脱传统经济增长方式、生产力发展路径&#xff0c;具有高科技、高效能、高质量特征&#xff0c;符合新发展理念的先进生产力质态。 **风口情报&#xff1a;**近日&#xff0c;中央经济工作会议首次提出“发展新质生产力”&#xff1b;…

glob path(python库)

glob 这里有两种方法导入glob mport glob #导入整个glob模块 from glob import golb #从glob模块导入glob函数 三种通配符 *代表0个或多个字符?代表一个字符[]匹配指定范围内的字符&#xff0c;如[0-9]匹配数字 #1、定义一个函数&#xff0c;搜索C盘下的所有文件和目录&…

作业1-32 P1059 [NOIP2006 普及组] 明明的随机数

题目 思路 根据题意&#xff0c;需要将读入的数据排序&#xff0c;去重。 参考代码 #include<bits/stdc.h> using namespace std; int n,a[5000],k;int main() {while(cin>>n){//读入数据for(int i0;i<n;i)cin>>a[i];sort(a,an);//排序int b[5000];in…

牛客 NC244138 剩下的数

链接&#xff1a;https://ac.nowcoder.com/acm/problem/244138 来源&#xff1a;牛客网 题目描述 牛牛有一个由 l … r l…r l…r 共 r − l 1 r−l1 r−l1 个整数组成的环。 牛妹对这个数环进行了 m m m 次询问&#xff0c;每次给定一个整数 x x x 问牛牛操作到不能继续…

python实例

设计者&#xff1a;ISDF工软未来 版本&#xff1a;v1.0 日期&#xff1a;2024/3/7 class Restaurant:餐馆类def __init__(self,restaurant_name,cuisine_type):#类的属性self.restaurant_name restaurant_nameself.cuisine_type cuisine_typeself.number_served 0def descri…

深度学习需要掌握哪些数学基础?

《深度学习的数学》这本书再合适不过了。作者罗纳德.T.纽塞尔&#xff08;Ronald T. Kneusel&#xff09;&#xff0c;拥有超过 20年的机器学习行业经验。 本书适合有一定深度学习基础、了解Python编程语言的读者阅读&#xff0c;也可作为用于拓展深度学习理论的参考书。 为什么…

贪心 Leetcode 738 单调递增的数字

单调递增的数字 Leetcode 738 学习记录自代码随想录 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的最大数字&#xff0c;且数字呈 单调递增 。 示例 1: 输入: n 10 输…

CKA考试必备:解锁Pod封装多容器的高级技巧!

往期精彩文章 : 提升CKA考试胜算&#xff1a;一文带你全面了解RBAC权限控制&#xff01;揭秘高效运维&#xff1a;如何用kubectl top命令实时监控K8s资源使用情况&#xff1f;CKA认证必备&#xff1a;掌握k8s网络策略的关键要点提高CKA认证成功率&#xff0c;CKA真题中的节点维…

Numpy中常用函数np.clip和np.finfo

NumPy&#xff08;Numerical Python&#xff09;是Python科学计算的核心库之一&#xff0c;提供了高性能的多维数组对象&#xff08;ndarray&#xff09;以及用于数组操作的各种函数和工具。 np.finfo finfo函数是根据括号中的类型来获得信息&#xff0c;获得符合这个类型的数…

【MySQL】用户管理 -- 详解

如果我们只能使用 root 用户&#xff0c;这样存在安全隐患。这时就需要使用 MySQL 的用户管理。 一、 用户 1、用户信息 MySQL 中的用户都存储在系统数据库 MySQL 的 user 表中。 字段解释&#xff1a; host&#xff1a;表示这个用户可以从哪个主机登陆&#xff0c;如果…

【三】【SQL Server】如何运用SQL Server中查询设计器通关数据库期末查询大题

数据库学生选择1122 数据库展示 course表展示 SC表展示 student表展示 数据库学生选课1122_1 第一题 第二题 第三题 第四题 第五题 数据库学生选课1122_2 第六题 第七题 第八题 第九题 第十题 结尾 最后&#xff0c;感谢您阅读我的文章&#xff0c;希望这些内容能够对您有所启…

修改MySQL字段类型 DECIMAL 小数点后面位数

1&#xff0c;下面是修改表字段的SQL语句&#xff1a; ALTER TABLE 表名称 MODIFY 字段名称 DECIMAL(10,5) COMMENT 说明; 2&#xff0c;浮点型: float(255,30): 单精度&#xff0c;总长度是255&#xff0c;小数位是30。 double(255,30):双精度&#xff0c;总长度是255&#…

实践:qemu 运行 linux riscv with AIA(APLICIMSIC)

RISCV架构 Linux AIA支持 目标&#xff1a;在 Qemu 中运行一个支持 riscv aia 的 linux 翻译参考自&#xff1a;https://lwn.net/Articles/963231/ 文章日期&#xff1a;2024年2月22日&#xff0c;星期四&#xff08;截至2024年3月&#xff0c;最新&#xff09; 这个网站里在不…

Spring Boot工程集成验证码生成与验证功能教程

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

《Vite 报错》ReferenceError: module is not defined in ES module scope

ReferenceError: module is not defined in ES module scope 解决方案 postcss.config.js 要改为 postcss.config.cjs&#xff0c;也就是 .cjs 后缀。 原因解析 下图提示&#xff0c;packages.json 中的属性 type 设置为 module。所有 *.js 文件现在都被解释为 ESM&#xff…

电商店群系统的搭建需要用到的官方接口如何申请?

电商电子商务企业往往都会需要再很多平台上面铺货&#xff0c;上传商品。 高科技的今天&#xff0c;我们已经不需要手动一个个品去上传了。那通过官方接口&#xff0c;如何实现快速铺货呢&#xff1f; 1688官方开放平台的API接口类型众多&#xff0c;并不是所有的企业都能申请…

GitHub Pages部署静态页面

GitHub Pages是GitHub提供的静态页面托管服务&#xff0c;可以用来托管个人博客、项目文档等静态页面。GitHub Pages支持Jekyll&#xff0c;可以使用Jekyll构建博客&#xff0c;也可以使用其他静态页面生成器。现在GitHub Pages也在公测通过工作流部署静态页面&#xff0c;可以…

鸿蒙文章专题-2021年鸿蒙相关的文章废弃

#原因 至于为什么说2021年我的鸿蒙专栏的文章废弃了&#xff0c;只是说没有了参考意义&#xff0c;是因为鸿蒙4.0以前的版本语言从以Java为主过渡为以ArkTS为主。以前的Java版本的工程已经无法再使用了&#xff0c;后续的开发都必须以ArkTS开发语言为主。 其中而且整个项目结构…

三. 开发环境搭建

目录 一. Ubuntu 和 Windows 文件互传 1.1 VMware Tools 1.2 FileZilla 二. Ubuntu 下 NFS 和 SSH 服务开启 2.1 NFS 服务开启 ​编辑 2.2 SSH 服务开启 三. Ubuntu 交叉编译工具链安装 四. vscode的remote-ssh远程连接虚拟机 4.1 Windows的vscode安装 4.2 vscode远…

chatGPT的耳朵!OpenAI的开源语音识别AI:Whisper !

语音识别是通用人工智能的重要一环&#xff01;可以说是AI的耳朵&#xff01; 它可以让机器理解人类的语音&#xff0c;并将其转换为文本或其他形式的输出。 语音识别的应用场景非常广泛&#xff0c;比如智能助理、语音搜索、语音翻译、语音输入等等。 然而&#xff0c;语音…