簡體   English   中英

具有合成綁定和可空性的 Kotlin 視圖

[英]Kotlin views with synthetic binding and nullability

我注意到當使用 Kotlin 的合成綁定時,返回的視圖是非空的(Kotlin 將返回View! )。 但這對我來說意義不大,因為findCachedViewById實際上可以返回空結果,這意味着視圖實際上可以為空。

public View _$_findCachedViewById(int var1) {
  if(this._$_findViewCache == null) {
     this._$_findViewCache = new HashMap();
  }

  View var2 = (View)this._$_findViewCache.get(Integer.valueOf(var1));
  if(var2 == null) {
     View var10000 = this.getView();
     if(var10000 == null) {
        return null;
     }

     var2 = var10000.findViewById(var1);
     this._$_findViewCache.put(Integer.valueOf(var1), var2);
  }

  return var2;
}

那么為什么在這種情況下它們不是可選的呢? 為什么 Kotlin 不直接返回View? 使用合成綁定時,開發人員在處理視圖時將被迫檢查可空性?

也許這只是因為我是 Kotlin 的新手,但我認為這有點違反直覺,因為變量不是可選的,但我們仍然應該檢查視圖是否實際上不為空。

那么在這種情況下,像下面的代碼那樣做有意義嗎?

view?.let {
    // handle non null view here
}

我想通了,我總是在發布我的問題后立即找到正確的 SO 問題:)

View后面的單個感嘆號實際上並不意味着視圖不能像我預期的那樣為 null。

This answer to another question基本上回答了我的確切問題。 View在使用合成綁定時實際上可以為 null,但我們無法確定,因此只有一個感嘆號。

因此,可以安全地假設我在上面發布的代碼 - 使用?.let{...}是處理視圖的完全可接受的方式,當您不確定它們在訪問它們時是否已經初始化時。

視圖可能為空的情況非常罕見,但它可能會發生。

正如您已經指出的那樣,單個感嘆號並不意味着它不是空的,而是它是一種 Java 平台類型,編譯器不知道它是否可以為空。

我認為你的建議很好,盡管它在 null 的實際情況下默默地失敗了,這實際上可能不是你想要的。

假設您試圖在 onCreateView 中調用您的視圖,但忘記了它尚未初始化。 該片段不會按預期運行,但不會產生有意義的錯誤來幫助您調試問題。

我仍在嘗試自己解決一個或另一個解決方案,但我建議要么顯式處理 null 的情況:

view?.let {
    //...
} ?: throwExceptionIfDebugElseLogToCrashlytics()

或者決定這次你真的希望它拋出 NullPointerException 在這種情況下我建議:

view!!.let {
    //...
}

后者不會因為“應該”是不可能的邊緣情況而使您的代碼膨脹,並且它不會悄無聲息地失敗,但它仍然讓讀者清楚地知道視圖可能為空。 顯然,。 編譯器不需要,它只是為了使處理平台類型的選擇策略更加明確。

如果您嘗試在活動或視圖的上下文之外或在 lambda 中從偵聽器訪問視圖,則合成視圖綁定實際上可能會發生空指針異常。

問題出在 lambda 中,Frantisek 在這里發布了相關信息:https ://stackoverflow.com/posts/comments/115183445?noredirect=1

這個想法是 Android 中的 xml 布局是相當靜態的,為了使用合成視圖,您必須創建一個已解析布局的直接導入:

import kotlinx.android.synthetic.main.activity_main.*

因此,在現實生活中,不存在View為空的非魔法場景。 除非你選擇了錯誤的合成布局,否則你會在第一次運行時崩潰。

也就是說,如果您在運行時修改視圖、刪除Views等,它當然會中斷。但同樣,這不是合成Views的默認用法,需要不同的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM