마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

createFromAsset으로 DB 사용시 에러 질문

0 추천

DB에 미리 채워진 데이터베이스가 필요해서 db browser for sqlite 를 사용해서

DB 파일을 생성한 뒤에 

코드에서 createFromAsset을 사용해서 패키지 아래 db 파일을 DB로 사용하려고 하고 있습니다.

만든 DB 파일은 아래와 같습니다.

 

그리고 아래와 같은 에러를 얻었습니다

E/AndroidRuntime: FATAL EXCEPTION: arch_disk_io_0
    Process: com.example.lightweight, PID: 3488
    java.lang.RuntimeException: Exception while computing database live data.
        at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:92)
        at androidx.room.TransactionExecutor$1.run(TransactionExecutor.java:47)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:920)
     Caused by: java.lang.IllegalStateException: Room cannot verify the data integrity. Looks like you've changed schema but forgot to update the version number. You can simply fix this by increasing the version number.
        at androidx.room.RoomOpenHelper.checkIdentity(RoomOpenHelper.java:154)
        at androidx.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:135)

Room cannot verify the data intergrity. ~~ 인데 

스택오버플로우에 검색해보니 저랑 같은 현상 겪는 사람들이 많더라구요. (그 사람들은 createFromAsset 방법을 사용한것같지는 않고 다른 방법을 사용한것 같습니다.)

아무튼 해결책으로 삭제/재설치를 해보라고해서 해보고 매니페스트에서 allowBackup~~ = false를 해보라 해서 시도해보는데 계속 같은 현상이 일어나는데, 어떠한 이유 떄문일까요?

---

WorkoutApplication

class WorkoutApplication : Application() {
    val database by lazy { WorkoutDatabase.getDatabase(this) }
    val workoutListRepo: WorkoutListRepository by lazy { WorkoutListRepository(database.workoutDao()) }
}

 

WorkoutDatabase

@Database(
    entities = [Workout::class, WorkoutSetInfo::class, WorkoutListTest::class],
    version = 1
)
@TypeConverters(UnitConverter::class, WorkoutListTypeConverter::class)
abstract class WorkoutDatabase : RoomDatabase() {
    abstract fun workoutDao() : WorkoutDao

    companion object {
        private var INSTANCE : WorkoutDatabase? = null

        @Synchronized
        fun getDatabase(context: Context): WorkoutDatabase {
            // if the INSTANCE is not null, then return it,
            // if it is, then create the database
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    WorkoutDatabase::class.java,
                    "workout_database"
                )
                    .createFromAsset("database/workout_database.db")
                    .build()
                INSTANCE = instance
                instance
            }
        }
    }
}

 

Dao

@Dao
interface WorkoutDao {
    @Query("SELECT * From WorkoutListTest")
    fun getWorkoutListTest() : List<WorkoutListTest>

    @Query("SELECT * FROM Workout")
    @Transaction
    fun getWorkoutSetInfoList() : LiveData<List<WorkoutWithSets>>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertWorkout(workout: Workout) : Long

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertSetInfoList(list: List<WorkoutSetInfo>)

    @Insert
    fun insertAll(list: List<Workout>)

    @Delete
    fun delete(detail: Workout)

    @Update
    fun update(list: List<Workout>)
}

 

ViewModel

class WorkoutListViewModel(val repository: WorkoutListRepository) : ViewModel(){
    private var _list = MutableLiveData<List<String>>(arrayListOf())
    
    val list: LiveData<List<String>>
        get() = _list

    fun getList(part: BodyPart) {
        viewModelScope.launch(Dispatchers.IO) {
            val result = repository.getWorkoutList(part)
            _list.postValue(result)
        }
    }
}

 

Repository

 

class WorkoutListRepository(private val workoutListDao: WorkoutDao) {
    fun getWorkoutList(part: BodyPart) : List<String> {
        val test: List<WorkoutListTest> = workoutListDao.getWorkoutListTest()

        val newList = test.map {
            it.workout
        }
        return when(part) {
            is BodyPart.Chest -> newList
            is BodyPart.Back -> newList
            is BodyPart.Leg -> newList
            is BodyPart.Shoulder -> newList
            is BodyPart.Biceps -> newList
            is BodyPart.Triceps -> newList
            is BodyPart.Abs -> newList
        }
    }
}

 

 

 

 

codeslave (3,940 포인트) 님이 2022년 12월 8일 질문

1개의 답변

0 추천
새로 설치하는 경우는 당연히 되야 할 것 같은데, 안된다니 이상하네요. 애뮬레이터를 아예 새로 만들고 해보시죠.
spark (227,470 포인트) 님이 2022년 12월 8일 답변
에뮬레이터가 아니라 무선 디버깅으로 휴대폰을 사용하고 있습니다ㅠ
클린빌드도 해보셨죠. 저도 이전에 같은 문제가 있었는데 앱 삭제 후 재 설치하니까 바로 해결됐었거든요.
Clean Proejct 말씀하시죠? 이거 후에 리빌드 프로젝트 후에 실행해봐도 그대로네요. 또 찾아보니 뭐 Room 해쉬값?이랑 관련있는거같은데 이거는 무슨 소린지 정확하게 몰겠네요..
앱을 새로 설치할 때는 문제가 없어야 하는데 이상하네요.
혹시 미리 배포한 db와 엔터티 구조가 일치하는지 확인해 보시구요  정 안되시면 폰을 리부트해 보시고 그래도 안되시면 버전을 2로 올려보세요.
스키마를 현재 DB에서 추축해서 비교해 보셔도 될 것 같네요.
https://stackoverflow.com/questions/56625795/create-android-room-entity-classes-from-db-file
...