Android Kotlinでコルーチンに取り組んでおります。
コードは断片的になっちゃうんですけど、下記の方法でコルーチンでDBにデータを追加するのをやってみました。
ボタンをタップすると、データが追加されるというものです。
//Purpose.kt
@Entity
data class Purpose constructor(
@PrimaryKey val purposeId: Int = 0,
val purpose: String
)
//PurposeDao.kt
@Dao
interface PurposeDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertOne(purpose: Purpose)
}
//TaskViewModel.kt
class TaskViewModel(private val repository: TaskRepository) : ViewModel() {
companion object {
val FACTORY = singleArgViewModelFactory(::TaskViewModel)
}
// Create a LiveData with a String
val currentTask: MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
fun onButtonClicked(context: Context) {
val coroutine_a = addTask(context)
}
//コルーチンのテスト
fun addTask(context: Context) {
viewModelScope.launch {
addTaskDb(context)
}
}
suspend fun addTaskDb(context: Context) {
try {
repository.addTask(context)
} catch (cause: Throwable) {
// If anything throws an exception, inform the caller
Log.e("TaskViewModel", "エラー でーたべーす")
Toast.makeText(context, "データベースエラーで更新できませんでした!", Toast.LENGTH_LONG).show();
}
}
}
//TaskRepository.kt
class TaskRepository(val purposeDao: PurposeDao) {
suspend fun addTask(context:Context) {
try {
//コルーチンのテストのために、とりあえずデータを指定
val purpose = Purpose(3, "がんばる");
purposeDao.insertOne(purpose)
} catch (cause: Throwable) {
Log.e("TaskRepository", cause.toString())
Toast.makeText(context, "Agent already exists!", Toast.LENGTH_LONG).show();
}
}
}
//MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.content_main)
val database = getDatabase(this)
val repository = TaskRepository( database.purposeDao)
// Get the ViewModel.
model = ViewModelProviders
.of(this, TaskViewModel.FACTORY(repository))
.get(TaskViewModel::class.java)
//中略
}
//AppDatabase.kt
@Database(entities = [Purpose::class], version = 2)
abstract class AppDatabase : RoomDatabase() {
//abstract fun purposeDao(): PurposeDao
abstract val purposeDao: PurposeDao
}
private lateinit var INSTANCE: AppDatabase
fun getDatabase(context: Context): AppDatabase {
synchronized(AppDatabase::class) {
if (!::INSTANCE.isInitialized) {
INSTANCE = Room
.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"task-admin"
)
.fallbackToDestructiveMigration()
.build()
}
}
return INSTANCE
}
そしたら、インストール時に上記のエラーが出て、ビルドできません。(´ω`)
色々と悩みましたが、アプリケーションのbuild.gradleを下記に変更したらできるようになりました。
annotationProcessor 'androidx.room:room-compiler:2.0.0'
implementation "androidx.room:room-ktx:2.0.0"
↓ 上記を下記に変更
annotationProcessor 'androidx.room:room-compiler:2.2.2' implementation "androidx.room:room-ktx:2.2.2"