Huaweiファミリーデバイスの場合のみAndroid.database.sqlite.SQLiteBlobTooBigExceptionが表示されます、Android 9 and 10
onUpgradeメソッドで、新しい列をテーブルに追加したい
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
...
case 43:
addColumn(db, TABLE_LESSONS, _SPEED_GAME_EASY_FINISHED, " INTEGER DEFAULT 0");
addColumn(db, TABLE_LESSONS, _SPEED_GAME_HARD_FINISHED, " INTEGER DEFAULT 0");
addColumn(db, TABLE_LESSONS, _MEMORY_GAME_EASY_FINISHED, " INTEGER DEFAULT 0");
...
}
private void addColumn(SQLiteDatabase db, String table, String column, String columnType) {
boolean isColumnExist = false;
AbstractWindowedCursor cursor = null;
String selectQuery = "SELECT * FROM " + table + " LIMIT 0,1";
try {
cursor = getSqlCursorWithIncreasedWindowSize(db.rawQuery(selectQuery, null));
if (cursor.moveToFirst()) {
isColumnExist = cursor.getColumnIndex(column) != -1;
}
if (!isColumnExist) {
db.execSQL("ALTER TABLE " + table + " ADD COLUMN " + column + columnType);
}
} finally {
if (cursor != null) {
cursor.close();
}
}
}
カーソルウィンドウのサイズを大きくしようとしましたが、役に立ちませんでした
fun getSqlCursorWithIncreasedWindowSize(cursor: Cursor): AbstractWindowedCursor {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
val cw = CursorWindow(null, 10000L)
(cursor as AbstractWindowedCursor).window = cw
}
return cursor as AbstractWindowedCursor
}
TABLE_LESSONSには、10列の整数、長いテキスト、短いテキストが含まれます
cursor.moveToFirst()で問題が発生
Java.lang.RuntimeException:
at Android.app.ActivityThread.performLaunchActivity (ActivityThread.Java:3430)
at Android.app.ActivityThread.handleLaunchActivity (ActivityThread.Java:3614)
at Android.app.servertransaction.LaunchActivityItem.execute (LaunchActivityItem.Java:86)
at Android.app.servertransaction.TransactionExecutor.executeCallbacks (TransactionExecutor.Java:108)
at Android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.Java:68)
at Android.app.ActivityThread$H.handleMessage (ActivityThread.Java:2199)
at Android.os.Handler.dispatchMessage (Handler.Java:112)
at Android.os.Looper.loop (Looper.Java:216)
at Android.app.ActivityThread.main (ActivityThread.Java:7625)
at Java.lang.reflect.Method.invoke (Method.Java)
at com.Android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.Java:524)
at com.Android.internal.os.ZygoteInit.main (ZygoteInit.Java:987)
Caused by: Android.database.sqlite.SQLiteBlobTooBigException:
at Android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow (SQLiteConnection.Java)
at Android.database.sqlite.SQLiteConnection.executeForCursorWindow (SQLiteConnection.Java:904)
at Android.database.sqlite.SQLiteSession.executeForCursorWindow (SQLiteSession.Java:851)
at Android.database.sqlite.SQLiteQuery.fillWindow (SQLiteQuery.Java:62)
at Android.database.sqlite.SQLiteCursor.fillWindow (SQLiteCursor.Java:149)
at Android.database.sqlite.SQLiteCursor.getCount (SQLiteCursor.Java:137)
at Android.database.AbstractCursor.moveToPosition (AbstractCursor.Java:220)
at Android.database.AbstractCursor.moveToFirst (AbstractCursor.Java:259)
at com.kkk.english_words.data.local.db.DatabaseHelper.addColumn (DatabaseHelper.Java:31)
at com.kkk.english_words.data.local.db.DatabaseHelper.onUpgrade (DatabaseHelper.Java:161)
at Android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked (SQLiteOpenHelper.Java:417)
at Android.database.sqlite.SQLiteOpenHelper.getWritableDatabase (SQLiteOpenHelper.Java:313)
at com.kkk.english_words.data.local.db.DatabaseHelper.getDb (DatabaseHelper.Java:2)
at com.kkk.english_words.data.local.db.DatabaseHelper.getActivityTimeDbHelper (DatabaseHelper.Java:2)
at com.kkk.english_words.data.local.db.DatabaseHelper.getActivityTimeDbHelper (DatabaseHelper.Java:1)
at com.kkk.english_words.ui.main.MainActivity.onCreate (MainActivity.Java:187)
at Android.app.Activity.performCreate (Activity.Java:7458)
at Android.app.Activity.performCreate (Activity.Java:7448)
at Android.app.Instrumentation.callActivityOnCreate (Instrumentation.Java:1286)
at Android.app.ActivityThread.performLaunchActivity (ActivityThread.Java:3409)
at Android.app.ActivityThread.handleLaunchActivity (ActivityThread.Java:3614)
at Android.app.servertransaction.LaunchActivityItem.execute (LaunchActivityItem.Java:86)
at Android.app.servertransaction.TransactionExecutor.executeCallbacks (TransactionExecutor.Java:108)
at Android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.Java:68)
at Android.app.ActivityThread$H.handleMessage (ActivityThread.Java:2199)
at Android.os.Handler.dispatchMessage (Handler.Java:112)
at Android.os.Looper.loop (Looper.Java:216)
at Android.app.ActivityThread.main (ActivityThread.Java:7625)
at Java.lang.reflect.Method.invoke (Method.Java)
at com.Android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.Java:524)
at com.Android.internal.os.ZygoteInit.main (ZygoteInit.Java:987)
それを修正する方法について何かアイデアはありますか?
よろしく
列の作成時にクラッシュは発生せず、データをフェッチするときに発生します。データが大きすぎてカーソルに収まりません。
列が存在するかどうかを確認する場合は、sqlite_master
テーブルの代わりに( https://www.sqlite.org/faq.html#q7 )。
経験則として、AndroidではSQLiteの単一レコードにメガバイト単位でデータを保持することはお勧めしません。このデータをローカルに保存する以外に選択肢がない場合は、このデータをファイルに書き込み、そのパスをデータベースに保存することをお勧めします。