当前位置: 首页 > 知识库问答 >
问题:

Android Kotlin有条件地调用不同且不推荐的构造函数

刘安志
2023-03-14

我有一个用Kotlin编写的Android应用程序,带有一个扩展了DigitsKeyListener的类BaseKeyListener。我的最低SDK版本是21。该类当前正在调用一个不推荐使用的构造函数。然而,新的构造器只能从API级别26及以上的版本中获得。如何根据API级别有条件地调用构造函数?

不久前,我基本上发布了Android的相同问题,但该解决方案在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()
}

如果我必须使构造函数私有并实现一个新的实例模式,也提供了一个替代解决方案。然而,我不能使用这个解决方案,因为还有其他类从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()

如何解决这个问题?

共有1个答案

壤驷深
2023-03-14

您链接的Java解决方案基本上只是忽略了不推荐使用的构造函数,而只使用了不推荐使用的构造函数。我认为你最后的解决方案是最好的。它的使用情况并不比直接使用DigitKeyListener差——您仍然需要检查SDK版本。

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

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”)放在该行的前面,以确认DEPRECATION警告。

 类似资料:
  • 问题内容: 假设有人给您一个类,具有以下构造函数: 假设您要创建一个子类。您如何有条件地在中调用构造函数? 换句话说,进行这种工作的“正确”方法是什么? 问题答案: 是的,@ JohanSjöberg说了什么。 看起来您的示例也非常人为。没有神奇的答案可以解决这个问题:) 通常,如果您有一堆构造函数,则最好将它们重构为四个单独的类(一个类仅应负责一种类型的事情)。

  • 我有一个抽象的超类,它有一个形式的构造函数 并希望创建该抽象类的一个子类,该子类不是以字符串作为其第一个参数,而是采用一个表示给定字符串名称的整数值,例如,0代表某个字符串,1代表另一个字符串,依此类推。 当我尝试编写窗体子类(int number,int amount)的构造函数时,我得到一个格式为“Implicit super constructor is undefined.必须显式调用另一

  • 问题内容: 不推荐使用函数eregi()。我该如何替换eregi()。我尝试使用preg_match,但随后停止工作。 之前的代码: 代码然后: 问题答案: 期望其正则表达式参数位于一对定界符内。 因此,请尝试:

  • 问题内容: 我在Java中使用多个构造函数时遇到麻烦。 我想做的是这样的: 但是我不能,因为第二个构造函数不能调用另一个构造函数,除非它是第一行。 这种情况的常见解决方案是什么?我无法“在线”计算arg2和arg3。我以为也许可以创建一个构造助手方法来完成实际的构造,但是我不确定这是否“漂亮”…… 编辑 :由于我的某些字段是最终的,因此使用辅助方法也是有问题的,我无法使用辅助方法进行设置。 问题答

  • 问题内容: 我正在与colyseus(节点游戏服务器框架)进行服务器端聊天。我将typescript与module:commonjs一起使用,因为colyseus是基于commonjs构建的。 我有延伸的课。在运行时出现此错误: 和JavaScript的麻烦: 从打字稿类: 编译后删除有问题的行时,很容易跳过该错误。但是没有创建基类,这不是一个完整的解决方案。 我用谷歌搜索了这个问题,它似乎与ba

  • 问题内容: 我一直很好奇的东西 不建议在我的构造函数中包含try / catch块吗?我知道我可以让构造函数将异常抛出给调用方。你们喜欢像我在Constructor中完成的那样调用方法吗?在调用类中,您希望创建FileDataValidator的实例并在该实例上调用该方法吗?只是有兴趣听到一些反馈! 问题答案: 在显示的代码中,验证问题不会传达给正在创建此对象实例的代码。那可能不是一件好事。 变化