【问题标题】:Why is the error Type mismatch displayed after I update my Android Studio?为什么更新我的 Android Studio 后会显示错误类型不匹配?
【发布时间】:2019-08-08 03:14:41
【问题描述】:

代码 A 在我的旧版本中运行良好,现在我将我的 Android Studio 更新到 3.4.2,并 buildToolsVersion "29.0.1",并使用最新的 androidx。

但我收到错误类型不匹配,您可以看到图 1,我该如何解决?谢谢!

图片 1

代码 A

class PreferenceTool<T>(private val context: Context, private val name: String,  private val default: T) {

    private val prefs: SharedPreferences by lazy {       
        context.defaultSharedPreferences        
    }

    operator fun getValue(thisRef: Any?, property: KProperty<*>): T = findPreference(name, default)

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        putPreference(name, value)
    }

    @Suppress("UNCHECKED_CAST")
    private fun findPreference(name: String, default: T): T = with(prefs) {
        val res: Any = when (default) {
            is Long -> getLong(name, default)
            is String -> getString(name, default)
            is Int -> getInt(name, default)
            is Boolean -> getBoolean(name, default)
            is Float -> getFloat(name, default)
            else -> throw IllegalArgumentException("This type can be saved into Preferences")
        }
        res as T
    }

    @SuppressLint("CommitPrefEdits")
    private fun putPreference(name: String, value: T) = with(prefs.edit()) {
        when (value) {
            is Long -> putLong(name, value)
            is String -> putString(name, value)
            is Int -> putInt(name, value)
            is Boolean -> putBoolean(name, value)
            is Float -> putFloat(name, value)
            else -> throw IllegalArgumentException("This type can't be saved into Preferences")
        }.apply()
    }
}

添加内容 1

此外,我发现代码 B 和代码 C 都可以正确编译。我不知道为什么。似乎is String -&gt; getString(name, default) 导致错误。

代码 B

@Suppress("UNCHECKED_CAST")
private fun findPreference(name: String, default: T): T = with(prefs) {
    val res: Any = when (default) {
        is Long -> getLong(name, default)
        else -> throw IllegalArgumentException("This type can be saved into Preferences")
    }
    res as T
}

代码 C

@Suppress("UNCHECKED_CAST")
private fun findPreference(name: String, default: T): T = with(prefs) {
    val res: Any = when (default) {
        is Long -> getLong(name, default)
        is Int -> getInt(name, default)
        is Boolean -> getBoolean(name, default)
        is Float -> getFloat(name, default)
        else -> throw IllegalArgumentException("This type can be saved into Preferences")
    }
    res as T
}

添加内容 2

prefs.getString(name, default) 似乎由 Image 2 返回 String?。不知道Build 29.0.1有没有bug?

图片 2

【问题讨论】:

    标签: android android-studio kotlin androidx


    【解决方案1】:

    这段代码无法编译,因为SharedPreferences.getString() 返回String?,它不是Any 的子类型。为什么之前能用,是bug吗?

    这不是一个错误,而是在 android sdk 中逐渐向 null-safety 转变。当 kotlin 成为 android 开发的官方语言时,they started to work on making android sdk kotlin-friendly。特别是,他们在 sdk 代码中添加了 @Nullable@NonNull 注释。但是立即这样做会破坏大量项目的编译,因此他们决定给开发人员一些时间来修复他们的代码:

    通常,Kotlin 中的可空性合同违规会导致编译错误。但为了确保新注释的 API 与您现有的代码兼容,我们使用 Kotlin 编译器团队提供的内部机制将 API 标记为最近注释。最近注释的 API 只会导致警告,而不是来自 Kotlin 编译器的错误。您将需要使用 Kotlin 1.2.60 或更高版本。

    我们的计划是让新添加的可空性注释仅产生警告,并从次年的 Android SDK 开始将严重级别提高到错误。目标是为您提供足够的时间来更新您的代码。

    正如他们所说,他们会提高后续 SDK 的严重性级别,而这正是这里发生的情况。但是SharedPreferences的源代码并没有改,那是怎么回事呢?答案是@RecentlyNullable

    (1) 这里有一些注解在支持库中是没有的,比如@RecentlyNullable 和@RecentlyNonNull。这些仅在存根中用于自动将代码标记为最近使用 null/non-null 注释。我们不希望源代码中有这些注释;最近在构建时计算并注入到存根中以代替正常的空注释。

    尽管SharedPreferences.getString 很久以前就被@Nullable 注释了,但显然他们的自动最近性计算决定在android P 中将其标记为@RecentlyNullable。为了证明这一点,让我们看一下反编译的代码。

    Android P:

    @RecentlyNullable
    String getString(String var1, @RecentlyNullable String var2);
    

    Android Q:

    @Nullable
    String getString(String var1, @Nullable String var2);
    

    【讨论】:

    • "如何解决" - 你可以在 getString 行中添加?: default 吗?
    • @AjahnCharles 当然,这将解决问题并且在这种情况下看起来像是合适的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2017-01-04
    • 2022-06-29
    • 2021-04-28
    • 1970-01-01
    • 2021-05-20
    • 2016-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多