【问题标题】:Android Kotlin call different and deprecated constructor conditionallyAndroid Kotlin 有条件地调用不同且已弃用的构造函数
【发布时间】:2020-03-11 22:41:34
【问题描述】:

我有一个用 Kotlin 编写的 Android 应用程序,其类 BaseKeyListener 扩展了 DigitsKeyListener。我的最低 SDK 版本是21。该类当前正在调用已弃用的构造函数。但是,新的构造函数仅在 API 级别 26 及更高级别可用。 如何根据 API 级别有条件地调用构造函数?

我基本上在不久前为 Android 发布了 the same problem,但该解决方案似乎在 Kotlin 中不起作用。

在 Kotlin 中,我的课程现在看起来像这样:

// primary constructor 'DigitsKeyListener' shows lint warning about deprecation.
abstract class BaseKeyListener() : DigitsKeyListener() {

}

如果我为 Android 问题应用解决方案,我会得到以下代码:

abstract class BaseKeyListener : DigitsKeyListener {

    // still results in deprecation warning
    constructor() : super()
}

如果我必须将构造函数设为私有并实现 newInstance 模式,还提供了一个替代解决方案。但是我不能使用该解决方案,因为还有其他类继承自 BaseKeyListener 并且 BaseKeyListener 也是抽象的。

我唯一能想到的是:

abstract class BaseKeyListener : DigitsKeyListener {

   constructor()

    @RequiresApi(Build.VERSION_CODES.O)
   constructor(locale: Locale) : super(locale)
}

但结果我必须为每个子类定义两个构造函数。如果我使用这个类,我每次都必须添加一个条件,而我们使用的语言环境是相同的。

不幸的结果:

open class AmountKeyListener : BaseKeyListener {

    constructor() : super()

    @RequiresApi(Build.VERSION_CODES.O)
    constructor(locale: Locale) : super(locale)
}

// usage of the keyListener
editText.keyListener = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) KeyListenerUtil.AmountKeyListener(
        MY_LOCALE) else KeyListenerUtil.AmountKeyListener()

理想的解决方案应该是将 AmountKeyListener 分配在一行上,并且 BaseKeyListener 应该知道何时使用我们的自定义语言环境“MY_LOCALE”

editText.keyListener = KeyListenerUtil.AmountKeyListener()

如何解决这个问题?

【问题讨论】:

    标签: android kotlin constructor deprecated keylistener


    【解决方案1】:

    您链接的 Java 解决方案基本上只是忽略弃用并专门使用弃用的构造函数。我认为你的最后一个解决方案是最好的。它的使用并不比直接使用 DigitsKeyListener 差——你仍然需要检查 SDK 版本。

    我在上面看到的一个小问题是,您的第一个构造函数隐式调用了空的超级构造函数,从而通过本质上是一种语言破解来避免弃用警告。真的,在我看来,这似乎是 Kotlin 代码检查器中的一个错误。我认为显式调用超级构造函数并在您自己的类中弃用此构造函数会更合适。所以我会让它看起来像这样:

    abstract class BaseKeyListener : DigitsKeyListener {
    
        @Suppress("DEPRECATION")
        @Deprecated("Use the constructor with a locale if on SDK 26+.")
        constructor(): super()
    
        @RequiresApi(Build.VERSION_CODES.O)
        constructor(locale: Locale) : super(locale)
    }
    

    这不会在功能上改变它的工作方式,但是在不弃用你的裸构造函数的情况下,很容易意外地在任何地方使用弃用版本的 DigitsKeyListener。

    在使用站点上,虽然很痛苦,但看起来就像在上面一样,除了您还要在该行之前加上 @Suppress("DEPRECATION") 以确认弃用警告。

    【讨论】:

    • 我不推荐使用您提到的构造函数。很好,您提到如果我直接使用 DigitsKeyListener 确实没有区别。我没有意识到这一点。
    猜你喜欢
    • 2017-07-19
    • 2013-05-22
    • 1970-01-01
    • 2017-05-02
    • 1970-01-01
    • 2013-10-28
    • 2021-09-10
    • 2017-12-04
    • 2011-07-18
    相关资源
    最近更新 更多