Nixo Home

Android中为什么非UI线程不能更新UI?

字数统计: 546阅读时长: 2 min
2019/07/01 Share

Android中为什么非UI线程不能更新UI?

面试官视角

  • 是否理解线程安全的概念(中级)
  • 是否能够理解UI线程的工作机制(高级)
  • 是否熟悉SurfaceView实现高帧率的原理(高级)

题目剖析(非UI线程更新UI)

  • UI线程工作机制
  • 为什么UI设计成线程不安全的
  • 非UI线程一定不能更新UI吗

UI线程是什么?

zygote 生成App进程后 打开ATP (ActivityThread)
ATP执行main函数 main函数里执行Looper.loop()
当loop死循环结束后会抛出异常

主线程如何工作

Handler.dispatchMessage(分发) <- Looper <- Handler.post

Looper->Main Thread -> Looper.loop->Looper

UI为什么不设计成线程安全的

如果UI设计成线程安全的,就必须加锁保证其UI的安全
既然加了锁,那也就会带来一定的开销,因为60针是UI流畅的
最低针,如果加了锁,可能会出现UI的卡顿以及不流畅的因素,带来极差的用户体验,所以UI不设计成线程安全的原因有以下几点

  • UI具有可变性,甚至是高频可变性

  • UI对相应时间的敏感性要求UI操作必须高效

  • UI组件必须批量绘制来保证效率

    非UI线程一定不能更新UI吗

  • 非UI线程不能直接更新UI,但是可以间接更新UI
    比如我们在非UI线程使用View.postInvalidate更新UI去重新绘制

  • 但是有一种情况,比如SurfaceView 可以在非UI线程直接刷新绘制UI

SurfaceView

prepar content -> lockCanvas -> draw -> unLockCanvasAndPost -> prepar content

↑ 整个过程运行在任何一个线程其实是都可以的

它可以实现一个高帧率,因为绘制放在了非UI线程,只要绘制完告诉UI线程显示就可以了,UI线程的压力就会小很多,比如游戏,地图。

本节回顾

  • 探讨UI线程或主线程的定义
  • 分析Android进程的启动流程
  • 分析Looper的工作机制
  • 探讨为什么UI不设计成线程安全的
  • 给出UI线程的其他存在形式
CATALOG
  1. 1. Android中为什么非UI线程不能更新UI?
  2. 2. 面试官视角
  3. 3. 题目剖析(非UI线程更新UI)
  4. 4. UI线程是什么?
  5. 5. 主线程如何工作
  6. 6. UI为什么不设计成线程安全的
  7. 7. 非UI线程一定不能更新UI吗
  8. 8. SurfaceView
  9. 9. 本节回顾