为什么在编译时分配字符串资源ID为正,而在运行时查找却为负?

时间:2019-12-17 17:57:50

标签: android string compilation resources id

我正在尝试通过其属性之一(即字符串资源ID)来标识对象。但是,从对象读取的字符串资源标识符与直接查找的字符串资源标识符的值不同。

// A data class with one property being a string resource ID
data class Foo(labelResId: Int, ...)

// An instance of Foo is created as a class property
private val foo = Foo(labelResId = R.string.my_string)

// I attempt to look up this specific object in a collection things
things.find { it is Foo && it.labelResId == R.string.my_string } // Fails to find foo

最后一行未能找到我的对象,因为it.labelResIdR.string.my_string返回的值即使最初都引用R.string.my_string也不同。但是,在将资源与标签资源ID进行比较之前将其分配给值会导致成功查找。

val targetResId = R.string.my_string
things.find { it is Foo && it.labelResId == targetRedId } // Successfully finds foo

R.string.my_string的形式查找时,资源ID为 -1901331 。在编译时分配给值时,资源ID为 2131887532 。到目前为止,我已经能够理解这两个数字之间的相关性,即max int以及Android如何在编译期间将R.string中的资源ID从R.string分配给R.java中的值,但是我不明白为什么内联{{1 }}也不会转换为正ID。

编辑1:这是我的代码的屏幕截图,以供澄清。对于上下文,此代码正在讨论RecyclerView中的“用户类型”下拉列表。

  1. 包含字符串资源ID属性的数据类 enter image description here

  2. 实例化一个FormDropdownRow实例,其中labelResId设置为R.string.user_type enter image description here

  3. 调试时的断点显示R.string.user_type的评估值(弹出评估气泡)与使用R.string.user_type构造时分配给FormDropdownRow :: labelResId的值不同(图片的右侧) enter image description here

  4. 现在,即使在构造FormDropdownRow的实例中将R.string.my_string设置为R.string.user_type时,该断点现在仍显示对“ when”条件的评估为假。位置19的项目是item.labelResId中FormDropdownRow的唯一实例;我不是偶然地比较了两个不同的项目。 enter image description here

编辑2:我开始认为此运行时错误与listItems的运行方式有关。例如,此代码无法分配正确的视图类型。

when

但是,此代码成功。

... = when (item = listItems[position]) {
  item is FormDropdownRow && item.labelResId == R.string.user_type -> USER_TYPE
  ...
}

此代码还可以成功分配正确的视图类型。

... = when (item = listItems[position]) {
  is FormDropdownRow -> if (item.labelResId == R.string.user_type) USER_TYPE else throw Exception()
...
}

我很困惑,因为上面的第一种情况和第三种情况对我来说都是相同的,尤其是因为IntelliJ建议用when块代替级联的if语句。

0 个答案:

没有答案