Не удалось прочитать строку 0, столбец 0 из CursorWindow, который имеет 0 строк, 64 столбца

Я когда-нибудь получу эту ошибку в своем логарифме.

Не удалось прочитать строку 0, столбец 0 из CursorWindow, который имеет 0 строк, 64 столбца.

Во-первых, немного назад. У меня есть приложение, которое работает на многих устройствах в нашей организации. В первую очередь, в настоящее время он работает примерно на 20 устройствах Samsung Note 8, 2 устройствах Samsung Note 10.1 и еще несколько других. Пока что проблема только на двух устройствах Note 8. На всех остальных устройствах все работает нормально.

Как работает приложение, пользователи используют приложение для сбора информации, текста, фотографий, подписи и т. Д. … и все это затем сохраняется / вставляется в базу данных SQLite в виде строки в таблице представлений. В таблице представлений содержится 64 столбца для сбора каждого поля. Существует метод синхронизации, который всегда выполняется (это AsyncTask, который выполняется внутри исполняемого потока , поэтому, даже если приложение закрыто, оно по-прежнему синхронизирует данные в фоновом режиме, если вы не закроете его из диспетчера задач Android ), Который синхронизирует данные с удаленным сервером и проверяет каждые 10 секунд, если требуется синхронизация, например, если новая вставка была вставлена, она затем начнет синхронизировать это представление. Когда представление завершено, синхронизируется с сервером и получает ответ об успешном завершении, он затем удаляется из базы данных устройства. До сих пор он работал отлично, и тысячи представлений были успешно синхронизированы и т. Д. Однако время от времени я получаю эту ошибку из одной или двух конкретных таблиц Note 8, которые воспроизводят эту проблему. Я пробовал много раз, чтобы создать ошибку, но она всегда работает, когда я тестирую ее, и я пробовал все типы сценариев для ее проверки.

Мой код – это тысячи строк, поэтому я постараюсь сохранить его как можно более актуальным. Во-первых, вот соответствующий код для runnable:

public Runnable myRunnable = new Runnable() { @Override public void run() { count ++; if(count >= 10) { android.util.Log.w(" SYNC ", "---------------"); android.util.Log.w(" SYNC ", "Checking if sync method is busy"); if(!syncBusy) { android.util.Log.w(" SYNC ", "Sync method OPEN"); doSync();//This will start doing sync. count = 0; } else { android.util.Log.w(" SYNC ", "Sync method BUSY, will try again in 10 seconds"); android.util.Log.w(" SYNC ", "---------------"); } } if(count == 1 && !syncBusy) { checkSubmissionsLefttoSync(); } mHandler.postDelayed(myRunnable, 1000); } }; 

Затем метод doSync () – это то, где я делаю загрузку, а также где я получаю ошибку. Это более тысячи строк, поэтому я не хочу публиковать код здесь. Я могу сказать, что он работает на 100% для всех устройств, за исключением одного или двух исключений, которые вызывают вышеупомянутую ошибку.

Кроме того, я опубликую часть, где я фактически пересекаю базу данных внутри метода синхронизации:

  databaseHelper = new Handler_Database(this); Cursor cursor2 = databaseHelper.getAllUnsyncedSubmissions(); if(cursor2.getCount() > 0) { if(cursor2.moveToFirst()) { do { try { //doing lookups here and populating sync arrays } catch (IllegalStateException e) { //Do Nothing } catch (NullPointerException e) { //Do Nothing } } while(cursor2.moveToNext()); } else { } } else { } cursor2.close(); databaseHelper.close(); в  databaseHelper = new Handler_Database(this); Cursor cursor2 = databaseHelper.getAllUnsyncedSubmissions(); if(cursor2.getCount() > 0) { if(cursor2.moveToFirst()) { do { try { //doing lookups here and populating sync arrays } catch (IllegalStateException e) { //Do Nothing } catch (NullPointerException e) { //Do Nothing } } while(cursor2.moveToNext()); } else { } } else { } cursor2.close(); databaseHelper.close(); 

Я заметил что-то еще, и я не уверен, что это проблема, однако, когда я запускаю приложение, logcat выводит следующую строку примерно 6 или 7 раз:

12: 48: 11.115 7416 # 7416 DEBUG SQLiteOpenHelper DB версия: 60

У меня есть свои собственные предупреждающие сообщения, когда приложение запускается, и те отображаются только один раз. Тем не менее, версия db и другая информация записываются несколько раз в logcat. Это проблема? Означает ли это, что у моей базы данных есть какая-то ошибка, которая создает несколько экземпляров?

Все приложения обновлены подписью apk из игрового магазина . Моя база данных onUpgrade метод выглядит следующим образом:

 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // Drop older table if existed db.execSQL("DROP TABLE IF EXISTS " + TABLE_SUBMISSIONS); // Create tables again onCreate(db); } 

Это отлично подходит для всех других планшетов и устройств. Все они автоматически обновляются из игрового магазина и продолжают работать так, как должны. Однако почему logcat выводит эти строки несколько раз?

Может ли это быть частью проблемы, почему я получаю ошибку, как упоминалось в начале этого сообщения?

Любое возможное понимание было бы с радостью оценено. Я вытаскиваю свои волосы в течение нескольких недель и не могу найти недостатки в моем коде.

ОБНОВЛЕНИЕ 1:

Я только что увидел это предупреждение:

08: 30: 58.710 16745 # 16745 WARN CursorWindow Окно заполнено: запрошенное распределение 307333 байта, свободное пространство 249426 байт, размер окна 2097152 байт

Я предполагаю, что это может быть причиной моих проблем. Любые идеи о том, как эффективно решить эту проблему?

ОБНОВЛЕНИЕ 2:

Я думаю, что решение может заключаться в ограничении столбцов, которые я получаю с помощью курсора. Например, все небольшие текстовые значения / столбцы. Затем после этого создайте новый запрос для каждого из столбцов, которые, как мне известно, занимают слишком много места. Считаете ли вы, что это решение? Кто угодно ?

ОБНОВЛЕНИЕ 3:

Это может сработать, я думаю, что я буду делать большие поля в отдельных курсорах после того, как исходный будет переработан. Что-то вроде этого (я только что написал некоторый код psuedo):

 Cursor c = db.rawQuery("SELECT Column1, Column2 .... FROM table " + ... , ...); 

Решение:

Смотрите мое решение здесь! https://stackoverflow.com/a/26797130/1518916

Я закончил свое решение, и теперь он отлично работает. В сущности, суть в том, что не стоит хранить большие данные в базе данных sqlite на Android. При работе с изображениями скорее сохраняйте только URI и сохраняйте изображение на устройстве. ОДНАКО, если вам нужно, я рекомендую не загружать все данные изображения в один и тот же курсор, разделять их и выполнять несколько запросов.

См. Мой ответ здесь https://stackoverflow.com/a/26797130/1518916

Эта ошибка возникает, когда ваши изображения имеют большой размер. Либо сохранить URL-адрес изображения, либо сжать изображение перед сохранением.

Intereting Posts