为何invalidate()不可以直接在UI线程中调用&invalidate与postInvalidate
1、android ui操作为什么一定要在主线程中执行?
答:Android UI操作是单线程模型,关于UI更新的相关API(包括invalidate())都是按照单线程设计的,对于多线程运行时不安全的,即在非主线程调invalidate()刷新界面出现异常。所以android禁止在非主线程更新UI。
2、为什么说invalidate()是线程不安全的?
答:在非UI线程中调用invalidate会导致线程不安全,也就是说可能在非UI线程中刷新界面的时候,UI线程(或者其他非UI线程)也在刷新界面,这样就导致多个界面刷新的操作不能同步,导致线程不安全。
3、为何invalidate()不可以直接在UI线程中调用?
答:Android主线程的执行,是通过Looper循环调度消息的机制运行的;主线程一直在执行Looper循环中,更新UI需要通过Handler往消息队列发送消息,Looper调度到以后便可以执行invalidate()。
android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。
Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他违背了Android UI操作的单线程模型。
invalidate方式刷新界面需要借助handler发送消息给UI线程,排队轮到时,收到刷新指令,才调用invalidate()开始刷新
postInvalidate方式底层的实现,是和上述invalidate方式一样的,借助于handler发送消息。源码参考https://blog.csdn.net/ziwang_/article/details/65690751
// 在onCreate()中开启线程
new Thread(new GameThread()).start();、
// 实例化一个handler
Handler myHandler = new Handler() {
// 接收到消息后处理
public void handleMessage(Message msg) {
switch (msg.what) {
case Activity01.REFRESH:
mGameView.invalidate(); // 刷新界面
break;
}
super.handleMessage(msg);
}
};
class GameThread implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
Message message = new Message();
message.what = Activity01.REFRESH;
// 发送消息
Activity01.this.myHandler.sendMessage(message);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
class GameThread implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// 使用postInvalidate可以直接在线程中更新界面
mGameView.postInvalidate();
}
}
}
为何invalidate()不可以直接在UI线程中调用&invalidate与postInvalidate的更多相关文章
- WPF非UI线程中调用App.Current.MainWindow.Dispatcher提示其他线程拥有此对象,无权使用。
大家都知道在WPF中对非UI线程中要处理对UI有关的对象进行操作,一般需要使用委托的方式,代码基本就是下面的写法 App.Current.MainWindow.Dispatcher.Invoke(ne ...
- 为什么说invalidate()不能直接在线程中调用
1.为什么说invalidate()不能直接在线程中调用?2.它是怎么违背单线程的?3.Android ui为什么说不是线程安全的?4.android ui操作为什么一定要在UI线程中执行? 1. ...
- Android 高级UI设计笔记17:Android在非UI线程中显示Toast
1. 子线程的Toast怎么显示不出来? 因为Toast在创建的时候会依赖于一个Handler,并且一个Handler是需要有一个Looper才能够创建,而普通的线程是不会自动去创建一个Looper对 ...
- Android开之在非UI线程中更新UI
当在非UI线程中更新UI(程序界面)时会出现例如以下图所看到的的异常: 那怎样才干在非UI线程中更细UI呢? 方法有非常多种.在这里主要介绍三种: 第一种:调用主线程mHandler的post(Run ...
- 一个解决在非UI线程中访问UI 异常的小方法
写 WPF 的童鞋可能都会碰到 在非UI线程中访问 UI 异常的问题.这是为了防止数据不一致做的安全限制. 子线程中更新UI还要交给主线程更新,引用满天飞,实在是麻烦. 接下来,我们推出一个可以称之为 ...
- 千万别在UI线程上调用Control.Invoke和Control.BeginInvoke,因为这些是依然阻塞UI线程的,造成界面的假死
原文地址:https://www.cnblogs.com/wangchuang/archive/2013/02/20/2918858.html .c# Invoke和BeginInvoke 区别 Co ...
- Android中高效的显示图片之二——在非UI线程中处理图片
在“加载大图”文章中提到的BitmapFactory.decode*方法,如果源数据是在磁盘.网络或其它任何不是在内存中的位置,那么它都不应该在UI线程中执行.因为它的加载时间不可预测且依赖于一系列因 ...
- 在线程中调用SaveFileDialog
在多线程编程中,有时候可能需要在单独线程中执行某些操作.例如,调用SaveFileDialog类保存文件.首先,我们在Main方法中创建了一个新线程,并将其指向要执行的委托SaveFileAsyn.在 ...
- 解决django或者其他线程中调用scrapy报ReactorNotRestartable的错误
官网中关于ReactorNotRestartable的错误描述(摘自:https://twistedmatrix.com/documents/16.1.0/api/twisted.internet.e ...
随机推荐
- HTML学习笔记Day9
一.宽高自适应 网页布局中经常要定义元素的宽和高:但很多时候我们希望元素的大小能够根据窗口或父元素自动调整,这就是自适应,元素自适应在网页布局中非常重要,tanenggou它能够使网页显示更灵活,可以 ...
- (贪心 部分背包问题)悼念512汶川大地震遇难同胞——老人是真饿了 hdu2187
悼念512汶川大地震遇难同胞——老人是真饿了 http://acm.hdu.edu.cn/showproblem.php?pid=2187 Time Limit: 1000/1000 MS (Java ...
- JavaSE_坚持读源码_HashMap对象_put_Java1.7
当你往HashMap里面put时,你其实在干什么? /** * Associates the specified value with the specified key in this map. * ...
- ansbile Tags && Block
Tags 官网示例:https://docs.ansible.com/ansible/2.6/user_guide/playbooks_tags.html 编写执行playbook的时候,每次修改完y ...
- 网络编程基础【day10】:我是一个线程(四)
本节内容 1.第一回 初生牛犊 2.第二回 渐入佳境 3.第三回 虎口脱险 4.第四回 江湖再见 第一回 初生牛犊 我是一个线程,我一出生就被编了个号:0x3704,然后被领到一个昏暗的屋子里,在这里 ...
- Java Web之上传文件
本篇文章你会学到 1. Apache FileUpload组件 2.上传文件保存的路径和名称问题 3.缓存大小和临时目录 4.控制文件上传的格式 先讲一个简单的例子,一个注册页面,有账号,邮箱,和头像 ...
- Office-kms
Office 2016 VOL Office Office 2016 Pro Plus 32 位专业增强版 文件名 SW_DVD5_Office_Professional_Plus_2016_W32_ ...
- Linux记录-shell获取hdfs表查询mysql
#!/bin/sh hdfs dfs -ls /user/hive/warehouse | awk '{print $8}' | awk -F "/" '{print $5}' & ...
- ruby--Hash方法汇总
一.给Hash添加默认值 :h = {1,2,3,4} #=> {1 => 2, 3 => 4} h.default = 7 h[1] ...
- 搭建idea下的vue工程
需要先安装好nodejs和npm 输入下面的命令查看是否成功安装 node -v npm -v 一.开始 工作目录:IdeaProjects使用idea新建Static Web项目:demo 在dem ...