当前位置: 首页 > news >正文

View绘制流程的源码所得

一些问题

子线程可以更新 UI 吗

答案是可以的,在特定的情况下可以

  1. 可以先在主线程中调用requestLayout() 方法,然后紧接着在子线程中更新UI(原理:不要在子线程触发 checkThread() 方法,而checkThread() 方法的调用时机是在requestLayout() 方法中,checkThread判断规则是判断调用线程是不是我所在的线程,不出意外的话,我所在的线程是主线程)
  2. 在子线程中创建ViewRootIml,(原理:ViewRootIml最初创建的是哪个线程,之后就可以(必须)一直在这个线程中更新UI,默认是主线程创建)因为他所在线程是子线程,直接运行会报错,因为子线程没有looper,需要Looper.prepare(); 之后就可以在这个子线程当中一直更新UI了(再换一个子线程也不行,主线程更新UI也会报错) Looper.loop();
  3. view的宽高为固定宽高也可以进行更新,因为在checkForRelayout() 方法中会宽高是否是matchParent或者固定值,如果是就不需要请求重新布局,或者高不是固定值,重绘后高度不会发生改变,直接重绘就行了(关闭硬件加速就不行了)绘制是不检查线程的
  4. 使用SurfaceView可以在子线程中更新UI

子线程吐司

报错:不能在一个没有Looper.prepare()的线程中吐司,同样的道理
Looper.prepare()
Toast.show(“aaa”)
Looper.loop()
也可以进行吐司

View绘制完成的宽度在哪个时刻能一定拿到?Activity的onStart?onResume?view.post { } ?

都不是,最好的是viewTree.observ

Window是个抽象类,他的实现类有哪些?

Window 只有一个实现类:PhoneWindow

布局通过setContentView传给Activity,他们是怎么结合到一起的?

Activity调用WindowsetContentViewPhoneWindow会关联DecorViewDecorView会匹配系统内置布局文件,默认的是ActionBar+FramLayout那个布局,FramLayoutidcontent,然后将我们传入的布局文件add进FramLayout

Activity在使用的过程中,从来没有new的操作,他是怎么来的?

ActivityThread创建,Activity的生命周期的调用,也是他在不同时机进行的,比如 handleLancherActivity会创建当前Activity,调用Activity的attach、onCreat

总结

子线程不是不能更新UI,而是谷歌工程师不让我们在子线程更新UI,是一种代码级别的约定,因为如果任意线程都能更新UI,那么系统工程师就需要做线程安全,每次更新UI都得执行加锁、解锁操作,浪费性能,还得考虑各种意外情况

出于成本考虑,强制让开发者在主线程更新UI,能解决掉非常大的性能问题和巨量的工作,所以说不允许在子线程更新UI

相关文章:

View绘制流程的源码所得

一些问题 子线程可以更新 UI 吗 答案是可以的,在特定的情况下可以 可以先在主线程中调用requestLayout() 方法,然后紧接着在子线程中更新UI(原理:不要在子线程触发 checkThread() 方法,而checkThread() 方法的调用时…...

企业级数据仓库-理论知识

D3 AM 大数据中间件 Hive:将SQL转化成分布式Map/Reduce进行运算,也支持转换成Spark,需要单独安装Hive集群才能访问Spark,支持60%的SQL,延迟比较大。SparkSQL:属于Spark生态圈,Hive on Sqark。HBase: NoSQL,高并发读,适…...

解决flutter不识别yaml里面配置的git项目

解决办法找到相应的 git路径,然后手动 git pull 暂时先用这个笨方法,后面有更好的解决办法了再说 studio 自己拉取的项目里面没有ios 和lib包...

rust结构体

一、定义结构体类型 语法 struct Name_of_structure {field1: data_type,field2: data_type,field3: data_type, }注意: 不同于C,Rust的struct语句仅用来定义类型,不能定义实例。 结尾不需要;。 每个字段定义之后用 , 分隔。最后一个逗号可…...

Python - 小玩意 - 键盘记录器

pip install keyboardimport keyboard import timedef get_time():date_time time.strftime("%Y-%m-%d %H:%S", time.localtime())return date_timedef abc(x):if x.event_type down:print(f"{get_time()}你按下了{x.name}")with open(./键盘记录器.txt,…...

msvcp71.dll丢失的解决方法分享,全面分析msvcp71.dll丢失原因

msvcp71.dll 丢失的问题可能困扰着许多使用 Windows 操作系统的用户。msvcp71.dll 是微软 C运行时库中的一个动态链接库文件,负责提供一些基本的函数和类,例如字符串处理、数学运算、文件操作等。如果这个文件丢失或损坏了,那么在使用依赖于它…...

stm32----ADC模数转换

一、ADC介绍 ADC,即模数转换器,它可以将模拟信号转化为数字信号。在stm32种一般有3个ADC,每个ADC有18个通道。 12位ADC是一种逐次逼近型模拟数字转换器,它有多达18个通道,可测量16个外部和两个内部信号源。各个通道的A…...

Unity SteamVR 开发教程:用摇杆/触摸板控制人物持续移动(2.x 以上版本)

文章目录 📕教程说明📕场景搭建📕创建移动的动作📕移动脚本⭐移动⭐实时调整 CharacterController 的高度 📕取消手部和 CharacterController 的碰撞 持续移动是 VR 开发中的一个常用功能。一般是用户推动手柄摇杆&…...

04条件构造器和常用接口

条件构造器和常用接口 wapper介绍 条件构造器的两个条件之间默认就是AND并列关系,如果需要或者的关系则需要调用构造器的or()方法 条件构造器类型作用Wrapper条件构造抽象类,最顶端父类AbstractWrapper生成SQL的where条件QueryWrapper封装查询或删除的条件UpdateWrapper封装修…...

什么是HTTP状态码?常见的HTTP状态码有哪些?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 什么是HTTP状态码?⭐ 1xx - 信息性状态码⭐ 2xx - 成功状态码⭐ 3xx - 重定向状态码⭐ 4xx - 客户端错误状态码⭐ 5xx - 服务器错误状态码⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前…...

vue3的双向绑定原理分析

谈到vue3的双向绑定原理,就得先知道,为什么vue2的双向绑定方式会被废弃? vue2的双向绑定 Object.defineProperty Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回…...

MySQL数据库时间计算的用法

今天给大家分享如何通过MySQL内置函数实现时间的转换和计算,在工作当中,测试人员经常需要查询数据库表的日期时间,但发现开发人员存入数据库表的形式都是时间戳形式,不利于测试人员查看,测试人员只能利用工具对时间戳进…...

应用在儿童平板防蓝光中的LED防蓝光灯珠

现在电子产品多,手机、平板电脑、电子书等等,由于蓝光有害眼睛健康,于是市场上有很多防蓝光的眼镜、防蓝光的手机膜、防蓝光的平板,这些材料和设备到底有没有用?如何正确预防蓝光危害呢? 我们现在所用的灯…...

BERT 快速理解——思路简单描述

定义: BERT(Bidirectional Encoder Representations from Transformers)是一种预训练的语言模型,它基于Transformer架构,通过在大规模的未标记文本上进行训练来学习通用的语言表示。 输入 在BERT中,输入…...

二叉树实现的相关函数

1.二叉树的创建 BTNode* BinaryTreeCreate(BTDataType* a, int n, int* pi) { if (n0||a[*pi] #){ (*pi);return NULL;}BTNode* root (BTNode*)malloc(sizeof(BTNode));root->_data a[(*pi)];root->_left BinaryTreeCreate(a, --n, pi);root->_right Binary…...

Redis面试题(二)

文章目录 前言一、Redis 支持的 Java 客户端都有哪些?官方推荐用哪个?二、Redis 和 Redisson 有什么关系?三、Jedis 与 Redisson 对比有什么优缺点?四、说说 Redis 哈希槽的概念?五、Redis 集群的主从复制模型是怎样的…...

STP介绍

目录 STP概述 二层环路带来的问题 1.广播风暴 2.MAC地址漂移问题 3.多帧复制---这个好理解,同一个数据帧被重复收到多次,被称为多帧复制。 802.1D生成树 STP的BPDU BPDU主要分为两大类 配置BPDU RPC COST 配置BPDU的工作过程 TCN BPDU TCN…...

numpy 和 tensorflow 中的各种乘法(点乘和矩阵乘)

嗨喽,大家好呀~这里是爱看美女的茜茜呐 👇 👇 👇 更多精彩机密、教程,尽在下方,赶紧点击了解吧~ python源码、视频教程、插件安装教程、资料我都准备好了,直接在文末名片自取就可 点乘和矩阵乘…...

(图论) 1020. 飞地的数量 ——【Leetcode每日一题】

❓ 1020. 飞地的数量 难度:中等 给你一个大小为 m x n 的二进制矩阵 grid ,其中 0 表示一个 海洋单元格、1 表示一个 陆地单元格。 一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边…...

c++ 重载、重写、覆盖

重载:指在同一作用域内,有多个同名但参数不同的函数的现象,叫重载;可以是任何用户定义的函数,例如 类成员函数、类静态函数、普通函数重写:子类重写父类的同名函数,只要子类出现有父类的同名函数…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 ​ 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...

Bean 作用域有哪些?如何答出技术深度?

导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答&#xff0c…...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...