Kotlin : Realmを用いてcsvファイルをセットする

##はじめに
Realmのデータベースを用いたデモアプリを作成していたとき、データベースが空の状態で登録や削除を行っていましたが、予めcsvファイルをセットしておく方法も試したので、忘れないように残そうと思います。



##build.gradleの設定
projectレベルのbuild.gradleを開き、以下の文をclasspathに加えます。

```php
classpath "io.realm:realm-gradle-plugin:10.2.0"
```
次にapplicationレベルのbuild.gradleを開き、以下のpluginを適用します。

```php
id 'realm-android'
```
ここで、言語がkotlinである場合は以下のpluginを適用する必要があります。このpluginは上記の'realm-android'より上に配置してください。

```php
id 'kotlin-kapt'
```
詳しい方法は[こちら](https://docs.mongodb.com/realm/android/install)

##Realmの初期化
次にRealmの初期化を行います。
初期化したいことを書くクラスにApplicationクラスがあり、このApplicationクラスを継承した新しいクラスを作成し、その中で初期化を行います。


```php:NewActivity.kt
package com.example.databasecsv

import android.app.Application
import io.realm.Realm

class NewActivity : Application() {

    override fun onCreate() {
        super.onCreate()

        //Realmの初期化
        Realm.init(this)
    }
}
```


##モデルクラスの作成
データベースの枠組みをクラスとして設定します。

先程と同様に新しいクラスを作成し、RealmObjectクラスを継承しクラスをオープンにします。
作成したクラス内でデータベースのフィールド（列）を設定します。

```php:ExDB.kt
package com.example.databasecsv

import io.realm.RealmObject

open class ExDB : RealmObject() {

    //フィールドの設定
    var exQuestion : String? = null
    var exAnswer : String? = null
    
}
```

##準備

- セットするCSVファイルを用意
このときファイルの名前はモデルクラス（ExDB）と同じに、フィールドもモデルクラスで宣言したもの（exQuestionやexAnswer）と同じにします。

- [Realm Studio](https://docs.realm.io/sync/realm-studio)をインストール
上のリンクからダウンロードしてできたら以下のようにしてセットしたcsvファイルからrealmファイルを作成
![2021-02-20 (16).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115122/fb4ab6b5-eaa4-3199-ded4-c77617c77ad2.png)
- realmファイルができないとき（Error : Failed to import data）
![2021-02-20 (21).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115122/b74a707f-1080-41f5-f1ca-767cd6ac0edd.png)
保存したcsvファイルをメモ帳で開き文字コードをUTF-8にしてからrealmファイルを作るとうまくいくことがあります

##realmファイルをAndroid Studioに取り込む
![2021-02-20 (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115122/af79d2fa-cd15-bc61-58d1-9a4b76a796b8.png)
Assetsフォルダを作成し、ここに先程のrealmファイル(test.realm)を配置します。
配置したらRealmの初期化の下に以下の設定を追加します。

```php:NewActivity.kt
val config = RealmConfiguration.Builder().assetFile("test.realm").build()
Realm.setDefaultConfiguration(config)
```

##リスト表示

```php:MainActivity.kt
package com.example.databasecsv

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ArrayAdapter
import io.realm.Realm
import io.realm.RealmResults
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    lateinit var realm : Realm
    lateinit var results : RealmResults<ExDB>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    override fun onResume() {
        super.onResume()

        realm = Realm.getDefaultInstance()

        results = realm.where(ExDB::class.java).findAll().sort(getString(R.string.db_field_question))

        val wordlist = ArrayList<String>()

        results.forEach{
            wordlist.add(it.exAnswer + " : " + it.exQuestion)
        }

        val adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, wordlist)
        listView.adapter = adapter

        }

    override fun onPause() {
        super.onPause()

        realm.close()
    }

```
```php:strings.xml
<string name="db_field_question">exQuestion</string>
```

##Error

![2021-02-20 (23).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1115122/beb8594b-fbe8-3e77-7024-5a9f085725c6.png)
上記のようなエラーが出た場合は以下の文を追加することで消えました。

```php:strings.xml
<application
        //省略
        android:name=".NewActivity">
        //省略
</application>
```


>Execution failed for task ':app:kaptDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
   > java.lang.reflect.InvocationTargetException (no error message)

このエラーがなかなか消えなかったのですが、kotlinのバージョンを1.4.20>1.3.50に下げることで消えました。
（間違った方法でしたら申し訳ありません。[こちら](https://stackoverflow.com/questions/64184076/room-db-java-lang-reflect-invocationtargetexception)を参考にしました）