〈kotlin〉Android studioでRealmを使いたい

金宏和實さんの「作ればわかる!Androidプログラミング kotlin対応」を参考に
Android studioでkotlinを使ってAndroidアプリ作成。

Realmを利用したアプリの作成が出てきたので、
Realmについて調べながらまとめてみる。

Realmとは

大量のデータを扱うときに利用するモバイルデータベース。
データのクラスの定義がそのままテーブル定義になり、実装が簡単になる。
SQLiteなどは、データベースとオブジェクトを対応づけるマッピングという処理が必要)
高速にデータベースの処理ができる。

Realmをインストールする

build.gradle(Project)

dependencies {
    classpath "io.realm:realm-gradle-plugin:10.9.0"
    //classpathを追加、バージョンは確認する
}

build.gradle(Module)

plugins {
    id 'kotlin-kapt'
    id 'realm-android'
}

dependencies {
    implementation 'io.realm:android-adapters:4.0.0'
    //依存関係の指定を追加、バージョンは確認する
}

kaptはJavaのAnnotationProcessingをkotlinで使えるようにするために必要。
アノテーションは「注釈」を意味していて、
言語処理系(コンパイラなど)に伝達したい付加的な情報(メタデータ)を与え、データに意味づけをする。

Realmの実装

Realmの初期化

アプリ起動時にRealmの初期化を実行する必要がある。
Applicationクラスを継承したクラスを新たに作成し、起動時にonCreate内の処理が実行されるように設定。

CustomApplication.kt

class CustomApplication :Application() {
    override fun onCreate() {
        super.onCreate()
        Realm.init(this)
        //初期化
        val config=RealmConfiguration.Builder()
            .allowQueriesOnUiThread(true)
            .allowWritesOnUiThread(true)
            .deleteRealmIfMigrationNeeded()   //モデルクラスを変更した際にエラーが出なくなる
            .build()
        Realm.setDefaultConfiguration(config)
        //デフォルト設定として保存。
    }
}

本書の実装では、

val config=RealmConfiguration.Builder().build()
Realm.setDefaultConfiguration(config)

となっていたがこれでは動作せず、エラーメッセージに設定の変更が出た。
このあたりはこれが良さそう。
https://docs.mongodb.com/realm/sdk/android/quick-start-local/

CustomApplicationは作成しただけでは実行されないため、AndroidManifest.xmlに追記が必要。

<application
    android:name=".CustomApplication"
    android:allowBackup="true"
    //省略
</application>
データのクラス定義をする

クラスをそのままデータベースに使うため、新しくモデルクラスを作成する。

open class DataClass :RealmObject(){
    //各データを識別するためのアノテーション、idがプライマリキーになる。
    @PrimaryKey
    var id:Long = 0
    var data:Long = 0
}

kotlinのクラスはデフォルトでは継承が禁止になっている。
モデルクラスはRealm内部で継承されるため、openをつけて継承できるようにする。

データを入力するアクティビティの設定
class EditActivity : AppCompatActivity() {
    private lateinit var binding :ActivityEditBinding
    private lateinit var realm : Realm

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        realm = Realm.getDefaultInstance()

        private fun insertData() {
            realm.executeTransaction {
                val maxId = realm.where<Data>().max("id")
                val nextId = (maxId?.toLong() ?: 0L) + 1L
                val data1 = realm.createObject<Data>(nextId)
                data1.data = 1
                //実際に入れたい値を作成したデータオブジェクトに設定
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        realm.close()
    }
}

onCreate()メソッド内でRealmのインスタンスを取得する。
Realm.getDefaultInstance()で先に作成したCustomApplication.ktから初期設定を読み込む。

realmの更新処理は必ずトランザクションの中で行う。
where<モデルクラス>とすることでデータの検索ができる。
今回はidの最大値を取得して、id+1を次のプライマリキーとして設定した。
realm.createObject<モデルクラス>(プライマリキー)でデータオブジェクトを作成できる。

onDestroy()メソッドでclose()を実行してRealmのインスタンスを閉じる。