Существует две вероятные проблемы, каждая из которых может привести к исключению, которое можно определить, просмотрев журнал.
Проблема 1 - столбец не найден
Первая общая проблема заключается в том, чтостолбец был добавлен в таблицу путем изменения кода, используемого методом onCreate .
- например, вы, возможно, изменили SQL для создания таблицы, включив определение столбца COLUNA_IMG с момента запуска приложения.
Метод onCreate запускается только один раз, когда база данных была впервые создана.Он не запускается каждый раз, когда запускается приложение, или каждый раз, когда создается экземпляр класса DatabaseHelper.
Эта проблема может быть определена путем просмотра журнала, и в этом случае вы можете найти что-то похожее на: -
2019-03-05 11:17:10.446 8872-8872/aaa.so54989458 E/SQLiteLog: (1) no such column: img
2019-03-05 11:17:10.447 8872-8872/aaa.so54989458 D/AndroidRuntime: Shutting down VM
2019-03-05 11:17:10.455 8872-8872/aaa.so54989458 E/AndroidRuntime: FATAL EXCEPTION: main
Process: aaa.so54989458, PID: 8872
android.database.sqlite.SQLiteException: no such column: img (code 1 SQLITE_ERROR): , while compiling: SELECT codigo, titulo, autor, img FROM livros WHERE titulo=? AND autor=?
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:903)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:514)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1408)
at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1255)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1126)
at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1332)
at aaa.so54989458.DBHelper.selecionarLivro(DBHelper.java:70)
at aaa.so54989458.MainActivity$2.onItemClick(MainActivity.java:78)
at android.widget.AdapterView.performItemClick(AdapterView.java:318)
at android.widget.AbsListView.performItemClick(AbsListView.java:1159)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3136)
at android.widget.AbsListView$3.run(AbsListView.java:4052)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
- Обратите внимание , что если вы используете Android Studio, то она выделяет строку в aaa.so54989458.DBHelper.selecionarLivro (DBHelper.java:70) и, нажав на ссылку, вы перейдете к коду, в котором возникло исключение в вашем коде.
- (обратите внимание, что метод, в котором произошла ошибка, является вашим selecionarLivro методом, другие аспекты, такие как имя класса и пакета, будут соответствовать вашему коду).
Исправление для проблемы 1
Исправление для вышеуказанной проблемы, было бы сделать одно из следующих действий: -
- Удалить / Очистить приложениеданные (через настройки).
- Удалите приложение
Затем, если код верен, перезапустите приложение.
Проблема 2 - Изображение слишком большое.
Изображения не являются идеальными кандидатами для хранения в базах данных, лучше хранить то, что указывает на используемое изображение (например, путь к изображению).Само изображение состоит из байтов, часто очень большого количества байтов.Хотя SQLite может содержать довольно большие изображения.
Реализация Android SDK, которая извлекает данные в Курсор, является более строгой.
Курсор, по сути, является буфером, который содержит частичный снимок всех данных.Базовый моментальный снимок, окно курсора, в Android SDK ограничен 2M, и он должен содержать как минимум одну строку.Вам гарантирован сбой, если у вас есть изображение размером 2M или более.Вы, скорее всего, получите сбой или проблемы, если изображение, скажем, больше 0,5M.
Пример ошибки, когда изображение слишком велико для окна курсора, даже если оно успешно сохранено в базе данных: -
2019-03-05 11:33:46.878 9059-9059/aaa.so54989458 W/CursorWindow: Window is full: requested allocation 2097152 bytes, free space 1789213 bytes, window size 2097152 bytes
2019-03-05 11:33:46.886 9059-9059/aaa.so54989458 W/CursorWindow: Window is full: requested allocation 2097152 bytes, free space 1983933 bytes, window size 2097152 bytes
2019-03-05 11:33:46.886 9059-9059/aaa.so54989458 W/CursorWindow: Window is full: requested allocation 2097152 bytes, free space 2096653 bytes, window size 2097152 bytes
2019-03-05 11:33:46.887 9059-9059/aaa.so54989458 E/SQLiteQuery: exception: Row too big to fit into CursorWindow requiredPos=3, totalRows=4; query: SELECT * FROM livros
2019-03-05 11:33:46.887 9059-9059/aaa.so54989458 D/AndroidRuntime: Shutting down VM
2019-03-05 11:33:46.895 9059-9059/aaa.so54989458 E/AndroidRuntime: FATAL EXCEPTION: main
Process: aaa.so54989458, PID: 9059
android.database.sqlite.SQLiteBlobTooBigException: Row too big to fit into CursorWindow requiredPos=3, totalRows=4
at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow(Native Method)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow(SQLiteConnection.java:859)
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:157)
at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:128)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:237)
at android.widget.CursorAdapter.getItemId(CursorAdapter.java:258)
at android.widget.AbsListView$RecycleBin.retrieveFromScrap(AbsListView.java:7105)
at android.widget.AbsListView$RecycleBin.getScrapView(AbsListView.java:6816)
at android.widget.AbsListView.obtainView(AbsListView.java:2365)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1408)
at android.widget.ListView.onMeasure(ListView.java:1315)
at android.view.View.measure(View.java:23169)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1535)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:825)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:704)
at android.view.View.measure(View.java:23169)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
at android.view.View.measure(View.java:23169)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
at android.support.v7.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:401)
at android.view.View.measure(View.java:23169)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:23169)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1535)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:825)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:704)
at android.view.View.measure(View.java:23169)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6749)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:716)
at android.view.View.measure(View.java:23169)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2718)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1572)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1855)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1460)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7183)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949)
at android.view.Choreographer.doCallbacks(Choreographer.java:761)
at android.view.Choreographer.doFrame(Choreographer.java:696)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
- Обратите внимание на первоетри строки для предыдущих строк, в которые может поместиться изображение (в основном в сообщениях говорится, что извините, не удалось получить больше строк, поскольку CursorWindow не заполнено.)
Исправление для проблемы 2
Простого исправления не существует, если вы не можете уменьшить размер изображений до приемлемого / управляемого размера.
Рекомендуемый подход - хранить изображения в другом месте, а затем сохранять путь или его часть вбаза данных.
- Вот пример, в котором используется комбинация сохранения пути к изображениям размером более 100 КБ в базе данных, но при сохранении изображения, если в базе данных не более 100 КБ (который может быть более эффективным ).