Kotlin 辅助对象 class 内存泄漏

Kotlin helper object class memory leak

我想创建一个辅助对象来帮助我从项目的任何位置访问字符串。这个辅助对象也应该在单元测试中工作。但是我不能确定是否存在内存泄漏的风险,例如使用?

这是辅助对象。

object ResourceHelper {

    private var getString: (Int) -> String = {
        it.toString()
    }

    private var getStringWithArgs: (Int, Array<out Any>) -> String = { id, args ->
        "$id${args.contentToString()}"
    }

    fun getString(@StringRes id: Int): String {
        return getString.invoke(id)
    }

    fun getString(@StringRes id: Int, vararg args: Any): String {
        return getStringWithArgs.invoke(id, args)
    }

    fun initialize(resources: Resources) {
        getString = { id -> resources.getString(id) }
        getStringWithArgs = { id, args -> resources.getString(id, *args) }
    }
}

这是项目中唯一的activity。

class MyActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
        super.onCreate(savedInstanceState, persistentState)
        ResourceHelper.initialize(resources)
    }
}

这是视图模型class,我不太了解引用是如何保存在堆栈中的。这种做法有什么问题吗?

class MyViewModel : ViewModel() {

    fun printString(id: Int) {
        val s = ResourceHelper.getString(id)
        Log.d("*****", s)
    }
}

由于配置更改,Activity 每次启动时 Activity 的 Resources 对象都是不同的。

您的代码将在 Activity 被销毁和下一次重新创建之间暂时泄漏 Resources 对象(在 onCreate() 中,当您再次调用 initialize() 并且覆盖通过引用持有的 Resources 对象)。如果那只是方向改变期间的时间,那是微不足道的。但是,如果是在用户退出 Activity 和他们下次 return 到该应用程序之间的时间段内,那么您的应用程序将占用比必要更多的内存。

无论如何,像这样的状态控制单例使单元测试变得困难。我建议创建扩展函数作为替代方法。如果您需要在 ViewModel 中访问字符串资源,您可以从 AndroidViewModel 扩展,它可以通过应用程序访问资源。

fun AndroidViewModel.getString(@StringRes id: Int) =
    getApplication<Application>().resources.getString(id)

fun AndroidViewModel.getString(@StringRes id: Int, vararg args: Any) =
    getApplication<Application>().resources.getString(id, args)