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

点击上方“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
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的医院后台管理系统实现了病房管理、病例管理、处方管理、字典管理、公告信息管理、患者管理、药品管理、医生管理、预约医生管理、住院管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让医院后台管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值