【问题标题】:Declare an enum with Android context class in static field warning在静态字段警告中声明一个带有 Android 上下文类的枚举
【发布时间】:2019-05-22 02:47:06
【问题描述】:

我希望在我的活动中添加一个枚举。 这个枚举将包含一个 EditText 类。

我在枚举中收到此警告:

Do not place Android context classes in static fields (static reference to Day which has field editText pointing to EditText); this is a memory leak

这是我的代码:

enum class Day(val num: Int, var editText: EditText?, val rStringInt: Int) {
    mon(2, null, R.string.lmon),
    tue(3, null, R.string.ltue),
    wed(4, null, R.string.lwed),
    thurs(5, null, R.string.lthurs),
    fri(6, null, R.string.lfri),
    sat(7, null, R.string.lsat),
    sun(1, null, R.string.lsun)
}

在我的活动中,我有一个 onCreate 方法,它手动分配每一天的 editText 值。我似乎无法在这里得到一个单行的东西:

Day.mon.editText = mon
Day.tue.editText = tue
Day.wed.editText = wed
Day.thurs.editText = thurs
Day.fri.editText = fri
Day.sat.editText = sat
Day.sun.editText = sun

如何才能使我在 Day 枚举中不会收到此错误?我已经尝试将枚举放在我的 Activity 类中,但它仍然给我一个警告。

编辑:对不起,这是一个警告,而不是错误。

【问题讨论】:

    标签: android kotlin enums


    【解决方案1】:

    您不应该将视图传递给默认为静态的枚举字段。视图绑定到活动的生命周期,静态字段持续整个应用程序流程的生命周期。因此,将视图分配给枚举字段可防止在不再使用该 Activity 时对相关 Activity 进行垃圾收集。这就是警告的意思。

    如果您只是想要一种简单的方法来访问您的视图,那么只需使用视图活页夹将它们包装起来。这将根据您的 XML 布局生成一个绑定类。

    https://codelabs.developers.google.com/codelabs/android-databinding/#0

    通过以上内容,您可以轻松地从自动生成的绑定类(例如代码实验室中的示例)访问您的视图。

    val binding : PlainActivityBinding =
    DataBindingUtil.setContentView(this, R.layout.plain_activity)
    
    binding.name = "Your name"
    binding.lastName = "Your last name"
    

    【讨论】:

    • 不过,这并没有解决将视图放入枚举的问题。由于枚举是静态的,如果我创建嵌套类呢?如果我在嵌套类中持有一个视图,这些会被垃圾收集器处理吗?
    • 或者只是活动之外的另一个类
    【解决方案2】:

    编辑:不过,当您的片段重新创建时,这会导致内存泄漏。 20 setonclicklisteners?算我一个 不过,我确实找到了另一种使用资源的方法。

    编辑:此数据应保存在片段中,因为它需要引用视图。因此,视图数据不应保存在另一个类或“枚举”中。 但是,另一个类仍然是保存不会更改的静态变量的好选择(例如从整数到字符串的引用)。 当视图被重新创建时,它会要求您转换所做的任何更改.. 使您的代码更加复杂。对于您“保存”的几行,这样做似乎不切实际。 另一种方法是不编辑以前的数据,只是不使用封装的以前的视图,仍然可以保存几行以设置点击侦听器。

    我采用了以下解决方案:

    使用嵌套的 Day 类创建一个单独的 Days 类,如下所示:

    class Days {
        val mon: Day = Day(2, null)
        val tue: Day = Day(3, null)
        val wed: Day = Day(4, null)
        val thurs: Day = Day(5, null)
        val fri: Day = Day(6, null)
        val sat: Day = Day(7, null)
        val sun: Day = Day(1, null)
    
        data class Day(val num:Int, var editText: EditText?)
    }
    

    然后,在我的活动中,我将其实例化:

    private val days: Days = Days()
    

    然后像这样引用它:

    days.mon.editText = mon
    days.tue.editText = tue
    days.wed.editText = wed
    days.thurs.editText = thurs
    days.fri.editText = fri
    days.sat.editText = sat
    days.sun.editText = sun
    

    这样,由于它不像枚举那样是静态的,因此它会与活动一起收集垃圾。

    如果您想知道,这个问题的上下文是为了遍历枚举(现在是对象)而建立的。这可以通过我的 Days 对象内部来实现:

    val days: Array<Day> = arrayOf(mon, tue, wed, thurs, fri, sat, sun)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-26
      • 2011-01-31
      • 1970-01-01
      • 2018-04-02
      • 1970-01-01
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多