android - 在 Kotlin 中创建单例类
问题描述
我想在 kotlin 中创建可以在将来发布的单例类。
这是代码。
companion object {
// Singleton prevents multiple instances of repository opening at the
// same time.
@Volatile
private var INSTANCE: AudioRepo? = null
@Volatile
private var counter: Int = 0
@JvmStatic
fun release() {
synchronized(this) {
// if counter is already 0 some sort of error has occurred
if (counter == 0)
throw IllegalStateException("Counter variable is 0")
counter--
if (counter == 0) {
INSTANCE!!.destroy()
INSTANCE = null
}
}
}
@JvmStatic
fun get(context: Context): AudioRepo {
// if the INSTANCE is not null, then return it,
synchronized(this) {
counter++
return INSTANCE ?: run {
val instance = AudioRepo(context.applicationContext as Application)
INSTANCE = instance
instance
}
}
}
}
请检查这是好还是我做错了什么。
这里的想法是,如果使用 get 获取实例,则需要使用 release() 释放它。计数器确定何时清除对象。
更新 由于大多数人似乎很困惑为什么我需要这种方法。让我解释。
AudioRepo 类需要在 UI 和 Service 中为 Singleton。由于我不能使用任何带刀柄的范围(我猜)使其成为单例,所以我使用了这种方法。
我不能单独使用 kotlin 对象类,我需要释放音频 repo 所包含的 Couroutine Scope 并取消注册 Content Observer。
我不能使用自动关闭(据我了解),因为我使用了 Jet Pack compose 和 In Service 的子可组合实例。
解决方案
我认为您应该考虑我的解决方案:
open class Singleton<out T : Any>(creator: () -> T) {
private var creator: (() -> T)? = creator
@Volatile
private var instance: T? = null
fun getInstance(): T {
val i = instance
if (i != null)
return i
return synchronized(this) {
val i2 = instance
if (i2 != null)
i2
else {
val created = creator!!()
instance = created
creator = null
created
}
}
}
}
- - 例子
class ImageLoader private constructor(){
companion object : Singleton<ImageLoader>(::ImageLoader)
}
推荐阅读
- mysql - 多个表的乘法和加法(简单的股票市场程序)
- kdb - KDB:如何将行从一个表插入/更新到另一个表
- linux - Linux中的atq作业数量有限制吗?
- python - PyOpenGL 对象不断围绕原点旋转
- javascript - 既然我们有 ES6 模块,我们应该回顾一下 AMD、CommonJS 等吗?
- c# - 为什么在 .NET 应用程序中使用 @Html.ActionLink 的导航栏菜单没有按我的预期工作?
- angular - Angular 有条件地更改组件的包装器
- php - 在 Symfony 4 中使用 remember_me 令牌自动登录时加载用户区域设置
- linq - 在 EF Core Linq 查询中连接表
- xamarin - 如何在 UWP 项目中创建 ContentDialog