我正在编写一个类,该类为多个活动缓存一些数据。期望该类对每个活动都通过一次初始化逻辑。但是,它也不应引起任何内存泄漏。
如果有人可以查看此代码以检查潜在的内存泄漏,将很有帮助。也欢迎其他评论。
class AbcManager private constructor(private val data : Abc) {
fun fromAbc(a : A) : B? = data.someMethod(a)
companion object {
private val abcManagerCache : MutableList<AbcManagerCacheItem> = mutableListOf()
fun of(context : Activity) : AbcManager {
val abcManagerFromCache = attemptFromCache(context)
if(abcManagerFromCache != null) return abcManagerFromCache
val newData = //some operation that uses the context
val abcManager = AbcManager(newData)
abcManagerCache.add(AbcManagerCacheItem(
context = WeakReference(context),
abcManager = abcManager
))
return abcManager
}
private fun attemptFromCache(context : Context) : AbcManager? {
abcManagerCache.forEach {
val contextFromCache = it.context.get()
if( null!= contextFromCache && context == contextFromCache) {
return it.abcManager
}
}
return null
}
private class AbcManagerCacheItem(
val context : WeakReference<Context>,
val abcManager : AbcManager
)
}
}
答案 0 :(得分:0)
我认为您可以使用WeakHashMap
并摆脱包装管理器类,从而变得更简单-
object AbcCache {
private val cache = WeakHashMap<Context, Abc>()
fun putInCache(context: Activity): Abc {
val dataFromCache = cache[context]
if (dataFromCache != null) return dataFromCache
val newData: T = //some operation that uses the context
cache[context] = newData
return newData
}
}
答案 1 :(得分:0)
使用WeakReference
最有可能防止您的代码在这里泄漏(尽管这取决于newData
是否对Context
进行了引用-我认为没有),维护了一个集合保持“活动”几乎从来不是一个好主意,并且(通常是)一个不良设计的标志。
尤其是这种集合是否具有静态性质时(如您的情况)。只要您的应用进程有效(可能需要几天或更长的时间),它就会一直存在,并且每次用户导航到另一个Activity
或执行配置更改时,它的大小都会增加。可以通过使用WeakHashMap
来减轻这种担忧,但是它并不能使它成为更好的体系结构。
如果每个AbcManager
实例仅初始化一次Activity
,为什么不将其保留为一个字段呢?如果您想确保在by lazy
处于适当状态之前不要实例化它,可以使用Activity
。