반응형
1. room 만들다 생긴 오류 수정
android AppDatabase_Impl does not exist 라는 에러가 발생.
KAPT란.
Kotlin에서 Annotation처리를 위해서 KAPT(Kotlin Annotation Processing Tool)을 제공
Project 내부에서 Hilt, Room, Databinding 같은 library가 사용된다면 필요
Kotlin은 kotlinc로 컴파일되기 때문에 기존에 Java로 작성된 Annotation Process로는 Kotlin의 Annotation이 제대로 처리되지 않음.
https://kotlinlang.org/ 의 Kotlin Gradle
plugins {
kotlin("kapt") version "1.6.10"
}
...
dependencies {
kapt("groupId:artifactId:version")
}
https://kotlinlang.org/ 의 groovy Gradle
plugins {
id "org.jetbrains.kotlin.kapt" version "1.6.10"
}
...
dependencies {
kapt 'groupId:artifactId:version'
}
몰라서 이렇게 했는데 됨. (다른 것들과 통일서 있게)
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
}
...
kapt "androidx.room:room-compiler:$room_version"
2. 전체소스
앱시작할 때 : db!!.contactsDao().getAll() //select
리스트 클릭했을 때 db?.contactsDao()?.delete(contacts = contacts) //delete
플러스 버튼을 눌렀을 때 : db?.contactsDao()?.insertAll(contact) //DB에 추가
build.gadle
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.example.room_test"
minSdk 26
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
viewBinding{
enabled true
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.2'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
def room_version = "2.3.0"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
kapt "androidx.room:room-compiler:$room_version"
}
AppDatabase.kt
package com.example.room_test
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities=[Contacts::class], version=1, exportSchema = false)
abstract class AppDatabase : RoomDatabase(){
abstract fun contactsDao() : ContactsDao
companion object{
private var instance:AppDatabase? = null
@Synchronized
fun getInstance(context:Context):AppDatabase?{
if(instance == null){
instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"database-contacts"
)
.allowMainThreadQueries()
.build()
}
return instance
}
}
}
Contacts
package com.example.room_test
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "tb_contacts")
data class Contacts (
@PrimaryKey(autoGenerate = true) val id:Long,
var name:String,
var tel:String
)
ContactsDao.kt
package com.example.room_test
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "tb_contacts")
data class Contacts (
@PrimaryKey(autoGenerate = true) val id:Long,
var name:String,
var tel:String
)
ContactsListAdapter.kt
package com.example.room_test
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.room_test.databinding.ItemContactsBinding
class ContactsListAdapter(private val itemList:List<Contacts>) : RecyclerView.Adapter<ContactsViewHolder>() {
interface OnItemClickListener{
fun onClick(v: View, position:Int)
}
private lateinit var itemClickListener : OnItemClickListener
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ContactsViewHolder {
val binding = ItemContactsBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ContactsViewHolder(binding)
}
override fun onBindViewHolder(holder: ContactsViewHolder, position: Int) {
val item = itemList[position]
holder.itemView.setOnClickListener{
itemClickListener.onClick(it, position)
}
holder.bind(item)
}
override fun getItemCount(): Int {
return itemList.size
}
fun setItemClickListener(itemClickListener:OnItemClickListener){
this.itemClickListener = itemClickListener;
}
}
class ContactsViewHolder(val binding:ItemContactsBinding): RecyclerView.ViewHolder(binding.root){
fun bind(item:Contacts){
binding.tvName.text = item.name
binding.tvTel.text = item.tel
}
}
MainActivity.kt
package com.example.room_test
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import com.example.room_test.databinding.ActivityMainBinding
import java.util.*
class MainActivity : AppCompatActivity() {
val TAG = "MainActivity"
var db : AppDatabase? = null
var contactsList = mutableListOf<Contacts>()
private lateinit var binding:ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
db = AppDatabase.getInstance(this)
val savedContacts = db!!.contactsDao().getAll() //select
if(savedContacts.isNotEmpty()){
contactsList.addAll(savedContacts)
}
val adapter = ContactsListAdapter(contactsList)
adapter.setItemClickListener(object:ContactsListAdapter.OnItemClickListener{
override fun onClick(v: View, position: Int) {
val contacts = contactsList[position]
db?.contactsDao()?.delete(contacts = contacts) //delete
contactsList.removeAt(position)
adapter.notifyDataSetChanged()
}
})
binding.rcv.adapter = adapter
binding.mPlustButton.setOnClickListener {
val random = Random()
val numA = random.nextInt(1000)
val numB = random.nextInt(10000)
val numC = random.nextInt(10000)
val rndNumber = String.format("%03d-%04d-%04d",numA,numB,numC)
val contact = Contacts(0, "New $numA", rndNumber) //Contacts 생성
db?.contactsDao()?.insertAll(contact) //DB에 추가
contactsList.add(contact) //리스트 추가
adapter.notifyDataSetChanged() //리스트뷰 갱신
}
}
}