1. ホーム
  2. android

[解決済み] Kotlinのパラメータ付きシングルトン

2022-12-28 14:05:37

質問

AndroidアプリをJavaからKotlinに変換しようとしています。アプリにはいくつかのシングルトンがあります。私はコンストラクタのパラメータを持たないシングルトン用のコンパニオンオブジェクトを使用しました。コンストラクタのパラメータを取る別のシングルトンがあります。

Javaコードです。

public class TasksLocalDataSource implements TasksDataSource {

    private static TasksLocalDataSource INSTANCE;

    private TasksDbHelper mDbHelper;

    // Prevent direct instantiation.
    private TasksLocalDataSource(@NonNull Context context) {
        checkNotNull(context);
        mDbHelper = new TasksDbHelper(context);
    }

    public static TasksLocalDataSource getInstance(@NonNull Context context) {
        if (INSTANCE == null) {
            INSTANCE = new TasksLocalDataSource(context);
        }
        return INSTANCE;
    }
}

kotlinでの私の解決策。

class TasksLocalDataSource private constructor(context: Context) : TasksDataSource {

    private val mDbHelper: TasksDbHelper

    init {
        checkNotNull(context)
        mDbHelper = TasksDbHelper(context)
    }

    companion object {
        lateinit var INSTANCE: TasksLocalDataSource
        private val initialized = AtomicBoolean()

        fun getInstance(context: Context) : TasksLocalDataSource {
            if(initialized.getAndSet(true)) {
                INSTANCE = TasksLocalDataSource(context)
            }
            return INSTANCE
        }
    }
}

何か見逃していませんか?スレッドの安全性?怠け癖?

似たような質問がいくつかありましたが、私はその答えが好きではありません :)

どのように解決するのですか?

Google のアーキテクチャ コンポーネントから、すてきな代替案を紹介します。 サンプルコード で、これは also 関数を使用しています。

class UsersDatabase : RoomDatabase() {

    companion object {

        @Volatile private var INSTANCE: UsersDatabase? = null

        fun getInstance(context: Context): UsersDatabase =
            INSTANCE ?: synchronized(this) {
                INSTANCE ?: buildDatabase(context).also { INSTANCE = it }
            }

        private fun buildDatabase(context: Context) =
            Room.databaseBuilder(context.applicationContext,
                    UsersDatabase::class.java, "Sample.db")
                    .build()
    }
}