本業の方が忙しく、多くの福岡市再開発が発表されている中記事を更新できずにいます。。。(泣)
今回の記事も本業のメモとしてAndroid開発時のRoomデータベース構築を書いていきます。
初期準備
Roomを利用するには専用のライブラリが必要です。
まずbuild.gradle(.app)に以下を追加しましょう。
plugins {
id "kotlin-kapt"
}
dependencies {
// room
def room_version = "2.4.3"
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"
}
フォルダ構成
次にフォルダ構成です。
Room関連のファイルは一つにまとめています。
java – com.example.textapp (applicationId)のフォルダ内に「Room」フォルダを作成し、以下のファイルを入れていきます。
AppDatabase.kt
(Table名).kt
(Table名)Dao.kt
Converter.kt (bitmap保存処理を書くクラス)
(Table名).ktと(Table名)Dao.ktクラスはTableを複数作成する際はその分作成が必要になります。
また、java – com.example.textapp (applicationId)のフォルダ内に、カスタムApplicationクラスを作成する必要があります。
テーブルクラス
テーブルを設定するクラスは、テーブルのデータクラスとDaoクラスが存在します。
データクラスには各カラムを設定し、Daoクラスでsql文などによる保存・取得処理などを書いていきます。
// Parcelize指定は強制ではないですが、Parcelizeにしておくことでこのデータクラスを受け渡ししやすくなります。
// @Parcelizeを利用するには別途ライブラリが必要です。
@Entity @Parcelize
data class User(
// primaryKeyは自動で設定されるIDになります。通常連番で登録されます。
@PrimaryKey(autoGenerate = true) val id : Int,
val name : String,
// 型指定でnull許容にすることでデータベースもnullableとなります。
val birthDay : String?,
// 初期値も設定できます。
val image : Bitmap? = null,
) : Parcelable
@Dao
interface UserDao {
// 登録処理
@Insert
fun insert(user: User)
// 更新処理
@Update
fun update(user: User)
// 削除処理
@Delete
fun delete(user: User)
// @Queryを付けることでSQL文を自由に設定できます。
@Query("delete from user")
fun deleteAll()
@Query("delete from user where id = :id")
fun deleteById(id: Int)
@Query("select * from user")
fun getAll() : MutableList<User>
}
Converterクラス
Converterクラスでは、通常Roomでは処理できない型(今回はBitmap)を保存できるようにする処理を書きます。
bitmapは処理できないので、処理が可能なbyteArrayに変換する処理が書かれています。
class Converter {
@TypeConverter
fun fromBitmap(bitmap: Bitmap) : ByteArray {
val outputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat. PNG ,100,outputStream)
return outputStream.toByteArray()
}
@TypeConverter
fun toBitmap(byteArray: ByteArray ) : Bitmap {
return BitmapFactory.decodeByteArray(byteArray,0,byteArray.size)
}
}
AppDatabaseクラス
RoomDatabaseを継承した抽象クラスです。
作成したテーブルDaoとConverterは全てここに記載します。
@TypeConverters(Converter::class)
@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract fun UserDao() : UserDao
}
カスタムApplicationクラス
アプリ全体でデータベースにアクセスするためにカスタムApplicationクラスを作成します。
class BaseApplication : Application() {
companion object {
lateinit var database: AppDatabase
}
override fun onCreate() {
super.onCreate()
database = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java,
"app_database",
).build()
}
}
カスタムアプリケーションクラスを作成した後はそのアプリケーションクラスをAndroidManifestでデフォルトに設定します。
<application
android:name="com.example.testapp.BaseApplication"
データベースの利用
MainActivityなどで利用する際の一例です。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: SavedInstanceState) {
val userDao = BaseApplication.database.UserDao()
runBlocking {
CoroutineScope(Dispatchers.Default).launch {
userDao.insert(0, "福岡 住男", "1992/08/09", bitmap)
}.join()
// 挿入後の処理
}
}
Roomで処理を行うには非同期が必須です。CoroutineScopeを利用し別スレッドで処理を行なっています。
runBlockingで囲んでおり、CoroutineScopeの処理を待った後に処理を行うことができますが、こちらは任意です。
コメント