<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      「Android面試」Android 子線程為什么直接更新UI?

        本文將從子線程不能更新UI的直接原因、根本原因、Android如何做到限制以及子線程該如何正確更新UI四個方向回答問題。

      【直接原因】在子線程中更新UI會怎樣?

      程序會出現以下錯誤: Only the original thread that created a view hierarchy can touch its views.

       

      【根本原因】看到問題的本質(根本原因)

      多線程操作UI是不安全的,那么為什么不安全?..

      假設子線程能夠更新UI,現在有個TextView顯示數字1,我們現在需要對這個textview的現在的數字加1顯示2,即 tv.text = tv.text +1 

       tv.text =  (tv.text.toString().toIntOrNull()?:0 + 1).toString()

      我們把這個模型簡化,這個計算類似于 x = x +1 的操作

      x = x +1

      那么證明 x = x +1不是線程安全的也就證明多線程操作  tv.text = tv.text +1 也不是安全的

      ??我們使用兩個線程分別去將x加10w,打印出x的值看看到底是多少?

      class MainActivity : AppCompatActivity() {
          override fun onCreate(savedInstanceState: Bundle?) {
              super.onCreate(savedInstanceState)
              setContentView(R.layout.activity_main)
      
      
              val tv = findViewById<TextView>(R.id.textview)
      
              for (i in 1..100000) {
                  xadd()
              }
              for (i in 1..100000) {
                  xadd()
              }
              Log.i("WQY0", "x = $x")
              Thread {
                  for (i in 1..100000) {
                      xadd()
                  }
                  Log.i("WQY1", "x = $x")
              }.start()
      
              Thread {
                  for (i in 1..100000) {
                      xadd()
                  }
                  Log.i("WQY2", "x = $x")
              }.start()
      
      
          }
          var x = 0
      
          fun xadd(){
              ++x
          }
      }

       

       

      理論上WQY0打印結果是20w,WQY1和WQY2其中有一個x打印結果是40w,但實際結果就是WQY1和WQY2都不是40w。所以多線程操作同一個資源是不安全的,對于UI操作也是同樣的,多線程操作UI時不安全的,這是根本原因。

       

      用鎖解決線程不安全的問題

      鎖能保證同一時間只能有一個線程訪問,具體如下

          @Synchronized
          fun xadd() {
              ++x
          }

      另一種寫法

          fun xadd() {
              synchronized(this) {
                  ++x
              }
          }

       原來的程序執行結果

       

       

      那么Android為什么不使用鎖的方式解決UI資源安全問題?

      鎖會影響代碼執行的效率。UI操作變慢的話界面卡頓,影響用戶體驗

       

      【如何限制】Android如何實現控制子線程直接更新UI?

       由于報錯是在ViewRootImpl,是View的requestLayout調用到ViewRootImpl的requestLayout,所以我們需要知道ViewRootImpl是什么,View(我們更新的TextView)和ViewRootImpl之間的關系又是什么?ViewRootImpl是在什么時候創建,以及什么時候調用ViewRootImpl.requestLayout方法?

      view setText的時候觸發了view的重繪,向下調用到父類view.requestLayout,最終執行到ViewRootImpl的requestLayout方法,所以在兩種情況下可以在子線程中更新UI,第一次ViewRootImpl創建之前,比如onCreate里面無延遲放在子線程中,第二種就是不會造成view的requestLayout,比如給view設置固定的尺寸。

       了解View的繪制流程,View的控件樹結構(下一篇)

       

      【如何更新】子線程想要更新UI怎么辦?

      跨線程通信的方式

      1、使用Handler

      2、Rxjava

      3、廣播、通知等

      子線程通過Handler切換到主線程更新UI (下一篇)

       

      posted @ 2024-08-08 19:14  茄子魚  閱讀(138)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 久久永久视频| 亚洲人成网站77777在线观看 | 成人自拍小视频在线观看| 韩国V欧美V亚洲V日本V| 亚洲av无在线播放中文| 久久婷婷大香萑太香蕉av人 | 国产偷窥熟女精品视频大全| 亚洲人成电影网站色mp4| 性欧美欧美巨大69| 国产成人无码av大片大片在线观看| 在线观看中文字幕国产码| 久久亚洲国产成人亚| 日韩中文字幕国产精品| 日韩在线观看 一区二区| 亚洲av永久无码精品水牛影视| 夜鲁鲁鲁夜夜综合视频| 亚洲综合国产伊人五月婷| 国产女人在线视频| 国产玩具酱一区二区三区| 尼玛县| 美欧日韩一区二区三区视频| 国产精品99久久免费| 潮喷失禁大喷水无码| 深夜福利视频在线播放| 日本五十路熟女一区二区| 亚洲人成电影网站 久久影视| 彰化县| 国产无遮挡真人免费视频| 中文无码热在线视频| 免费A级毛片中文字幕| 革吉县| 国产系列高清精品第一页| 国产成人不卡一区二区| 麻豆精品一区二正一三区| 久久亚洲精品国产精品| 中国少妇人妻xxxxx| 一区二区三区精品不卡| 久久精品夜夜夜夜夜久久| 婷婷综合缴情亚洲| 蜜臀av一区二区三区日韩| 男女xx00上下抽搐动态图|