2

After i insert fastly X records in my database the app at certain point crash with the following stack trace:

2021-03-17 15:25:22.766 26711-26827/it.gabtamagnini.visualstock E/SQLiteLog: (266) statement aborts at 34: [SELECT * FROM corpo WHERE id_testata = ? ORDER BY timestamp ASC] disk I/O error
2021-03-17 15:25:22.766 26711-26827/it.gabtamagnini.visualstock E/SQLiteQuery: exception: disk I/O error (code 266); query: SELECT * FROM corpo WHERE id_testata = ? ORDER BY timestamp ASC
2021-03-17 15:25:22.790 26711-26711/it.gabtamagnini.visualstock E/AndroidRuntime: FATAL EXCEPTION: main
    Process: it.gabtamagnini.visualstock, PID: 26711
    android.database.sqlite.SQLiteDiskIOException: disk I/O error (code 266)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:846)
        at android.database.sqlite.SQLiteSession.executeForCursorWindow(SQLiteSession.java:836)
        at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
        at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:143)
        at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:132)
        at it.gabtamagnini.visualstock.database.CorpoDAO_Impl$14.call(CorpoDAO_Impl.java:393)
        at it.gabtamagnini.visualstock.database.CorpoDAO_Impl$14.call(CorpoDAO_Impl.java:381)
        at androidx.room.CoroutinesRoom$Companion$createFlow$1$1.invokeSuspend(CoroutinesRoom.kt:81)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:764)

Actually i call the DAO method which calls the query which is in the stacktrace is in a observe method of onCreate of the activity, here is the code:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_lettura)
        setSupportActionBar(findViewById(R.id.toolbar))

        ...
        Transformations.switchMap(corpoViewModel.getIdTestata()) { id ->
            corpoViewModel.getCorpo(id.toInt())
        }.observe(this, { articoli ->
            when (val count = articoli.count()) {
                0 -> {
                    txtCountArticoli.text =
                        resources.getQuantityString(R.plurals.articoli, count, count)
                    if (bottomSheetBehavior.state == BottomSheetBehavior.STATE_EXPANDED) {
                        bottomSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED
                    }
                    bottomSheet.setBackgroundColor(Color.parseColor("#C3858585"))
                    bottomSheetBehavior.isDraggable = false
                }
                1 -> {
                    bottomSheet.setBackgroundColor(Color.parseColor("#3D5AFE"))
                    bottomSheetBehavior.isDraggable = true
                    txtCountArticoli.text =
                        resources.getQuantityString(R.plurals.articoli, count, count)
                }
                else -> {
                    bottomSheet.setBackgroundColor(Color.parseColor("#3D5AFE"))
                    bottomSheetBehavior.isDraggable = true
                    txtCountArticoli.text =
                        resources.getQuantityString(R.plurals.articoli, count, count)
                }
            }
            articoli.let { adapter.setData(articoli as MutableList<Corpo>) }
        })
}

I had the same issue even when i was inserting the rows in my db slowly and i can't get the cause of that error and i can't even realize how can i fix it.

Here is my dao:

@Query("SELECT * FROM corpo WHERE id_testata = :idTestata ORDER BY timestamp ASC")
fun getAll(idTestata: Int): Flow<List<Corpo>>

Here is the Repository:

@WorkerThread
fun getCorpo(idTestata: Int) : Flow<List<Corpo>>{
    return corpoDAO.getAll(idTestata)
}

And the ViewModel:

fun getCorpo(idTestata: Int): LiveData<List<Corpo>>{
    return repository.getCorpo(idTestata).asLiveData()
}

What is the issue of my app crash and how can i solve it?

EDIT:

i'm calling the .getCorpo even in the Fragment which is in that Activity

EDIT 2 (DB Instance):

@Database(entities = [Corpo::class, Prodotto::class, Barcode::class, Testata::class, Fornitori::class, PuntiVendita::class], version = 1, exportSchema = false)
abstract class PDTDatabase: RoomDatabase() {
    abstract fun corpoDao(): CorpoDAO
    abstract fun prodottiDao(): ProdottiDAO
    abstract fun testataDao(): TestataDAO
    companion object {
        @Volatile
        private var INSTANCE: PDTDatabase? = null

        fun getDatabase(context: Context): PDTDatabase {
            // 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,
                    PDTDatabase::class.java,
                    "visual_pdt"
                )
                    .fallbackToDestructiveMigration()
                    .build()
                INSTANCE = instance
                // return instance
                instance
            }
        }


    }
}

And then i set it in my Application() like this:

class ArticoliApplication : Application() {
    val database by lazy { PDTDatabase.getDatabase(this) }
    val repository by lazy { CorpoRepository(database.corpoDao(), database.prodottiDao(), database.testataDao()) }
}
NiceToMytyuk
  • 3,644
  • 3
  • 39
  • 100

1 Answers1

1

I'm not sure about the answer, tell me the result.

Based on sqlite documents and your code

(266) SQLITE_IOERR_READ

The SQLITE_IOERR_READ error code is an extended error code for SQLITE_IOERR indicating an I/O error in the VFS layer while trying to read from a file on disk. This error might result from a hardware malfunction or because a filesystem came unmounted while the file was open.

I think your db object instantiates twice. And you need to double-check the db instantiation: more about double check

companion object {
    @Volatile
    private var INSTANCE: PDTDatabase? = null

    fun getDatabase(context: Context): PDTDatabase {
        // if the INSTANCE is not null, then return it,
        // if it is, then create the database
        return INSTANCE ?: synchronized(this) {
            if (INSTANCE == null) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    PDTDatabase::class.java,
                    "visual_pdt"
                )
                    .fallbackToDestructiveMigration()
                    .build()
                INSTANCE = instance
            }
            INSTANCE
        }
    }
}
beigirad
  • 4,986
  • 2
  • 29
  • 52