阿里的专家说不能,当我这么做的时候竟然让他羞红了脸

点击上方“IT烂笔头”,选择“置顶公众号”

第一时间获取 IT 技术干货!

阅读文本大概需要 6 分钟。

1

UI 线 程 的 定 义

作为一名机智的安卓开发者,似乎每个人心里都有些公认的约定规则。不在非UI线程中更新UI一定是其中之一,你有没有想过官方为什么不建议我们在非UI线程中去更新UI?在回答这个问题之前,我们先简单了解下何为UI线程?

UI线程也就是我们平时讲的主线程,当系统的zygote进程folk出我们的应用进程时,会为应用进程创建ActivityThread,这个线程就是我们的主线程,一旦这个线程开启的时候,其中的Looper就一直死循环的在消息队列中接收消息用来处理UI相关业务。作为一个初级工程师这些基本能了解。

2

Looper 机 制

这里我借助网上的一张图简单释义下这个过程:


图中画的过程就是我们的Looper机制,这里就不再说了,想知道细节的同学可以看我另一篇专门写Looper的文章:Looper赏析
当然如果你之前已经看过我的文章了,对Looper机制了如指掌,那么作为一个中级工程师完全合格了。

3

为 什 么 UI 不 是 线 程 安 全 的

官方不让我们在非UI线程更新UI,原因是UI设计的并非线程安全的,多线程访问的时候必然会出现展示错乱,那么有人就会问了,那将UI设计成线程安全的不就行了吗?

 

OK,那么我们就假设将UI设计成线程安全的,那么当有很多线程去更新UI的时候,必然会涉及到上锁和释放锁,这个过程吃开销。而UI的更新频率是非常高的,显然不适合频繁的上锁和释放锁,所以官方将UI设计成只在一个线程去更新,也不需要线程安全。 

小结一下为什么UI不设计成线程安全的?

    • UI是频繁的变

    • UI需要高效的响应操作,不能频繁加锁

    • UI组件需要批量同时绘制保证高效

综上,UI就不宜设计成线程安全的。

 

那么有人讲了,那不对啊,我怎么记得可以在子线程更新UI呢?你看我是这么写的:

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fake);


        fakeText = findViewById(R.id.fake_tips);
        fakeText.setText("主线程");
        new Thread(new Runnable() {
            @Override
            public void run() {
                fakeText.setText("子线程");
                fakeText.setTextColor(Color.BLACK);
            }
        }).start();
    }

然后就能正常看到text变成“子线程”了,也没有报错啊。
然后,我们将代码稍作修改:

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fake);


        fakeText = findViewById(R.id.fake_tips);
        fakeText.setText("主线程");
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 线程等待500毫秒
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                fakeText.setText("子线程");
                fakeText.setTextColor(Color.BLACK);
            }
        }).start();
    }

我们让子线程沉睡了500毫秒以后再更新UI,这时候就报错了。如果你看过源码,其实你应该知道,只要你足够快,在主线程创建页面根布局之前去修改UI,就不会报错。其实这么做也没有实际意义,只是从咬文嚼字上说我们确实可以在子线程修改了UI。 

其实还有一个在子线程中更新UI的场景,实际使用的特别多。那就是SurfaceView,像我们的视频(VideoView)以及很多游戏都是使用SurfaceView来处理的,因为这些场景需要非常高的频率刷新UI,不太适合放到我们主线程的UI一起操作,所以他们就被设计成在自己单独的线程处理。 

我们将这个简单化的讲一下,更直白一点就是主线程里面的UI都在同一个window里面,SurfaceView相当于在这个window里面挖了个洞,SurfaceView就是显示在洞的后面也就是window的后面,你可以在洞的上方放一些View,这样看起来就是SurfaceView上面叠加了一些普通的View。

推荐阅读:

高工做CPU架构适配的心得体会

听了他讲的泛型,我就明白为什么他的工资比我多30万了!

千万别告诉别人,这是我从高工那偷听来的Java方法分派策略

THANDKS

- End -

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用明 YOLO高分设计资源源码,详情请查看资源内容中使用明 YOLO高分设计资源源码,详情请查看资源内容中使用明 YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用
YOLO高分设计资源源码,详情请查看资源内容中使用明 YOLO高分设计资源源码,详情请查看资源内容中使用明 YOLO高分设计资源源码,详情请查看资源内容中使用明 YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用明YOLO高分设计资源源码,详情请查看资源内容中使用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值