5

Robię aplikację kiosku, która korzysta z bazy danych. Aplikacja działa cały czas na pierwszym planie. Aplikacja ma wiele wątków, które używają jednej współużytkowanej instancji DataBaseHelper. Aplikacja działa bez zarzutu, ale przez większość czasu po 5 lub 6 godzin, spotykam tych wyjątków następnie awarii aplikacji:Alokacja okna kursora o wartości 2048 kb nie powiodła się. # Open Cursors = 1 (# kursory otwarte przez ten proc = 1)

E/DataBaseHelper: Cursor przydział okno 2048 kb nie powiodło się. # Otwartych kursory = 1 (# kursory otwarty przez ten proc = 1)

E/CursorWindow: Nie można przydzielić CursorWindow '' z /data/user/0/com.kios.frm/databases/YadProjectDB.db rozmiar 2097152 z powodu błędu -24.

E/SQLiteLog: (14) może plik nie jest otwarty na linii 30192 z dnia [00bb9c9ce4]

E/SQLiteLog: (14) oświadczenie przerywa na 16: [numer wybrać spośród sms limit 5] Nie można otworzyć bazy danych plik

E/SQLiteQuery: wyjątek: nie można otworzyć pliku bazy danych (kod 14);
zapytania: Wybierz numer Z sms limit 5

E/SQLiteLog: (14) os_unix.c: 30192: (24)
otwartego (/data/user/0/com.kiosk.frm/databases/YadProjectDB .db-journal) -

Prawidłowo zamknąłem kursor, ale nadal otrzymuję te wyjątki. jakie są te wyjątki? jaka jest przyczyna tych wyjątków? Sposób

główną działalność

private DataBaseHelper db = null; // Global  

główną działalność onCreate class

db = new DataBaseHelper(this); 

new Thread(new Runnable() { 
@Override 
public void run() { 
    while (threadRunningFlag) { 

    Cursor result = null; 
    try { 

     result = db.getData("SELECT " + DataBaseHelper.SMS_COLUMN_PHONE_NUMBER + " FROM " + DataBaseHelper.SMS_TABLE_NAME + " LIMIT 5"); 
     if (result != null && result.getCount() > 0) { 
      while (!result.isAfterLast()) { 
       String phoneNumber = result.getString(result.getColumnIndex(DataBaseHelper.SMS_COLUMN_PHONE_NUMBER)); 
       // ... 
       result.moveToNext(); 
      } 
     } 
    }catch (Exception e) { 
     Log.e(TAG, "err->" + e.getLocalizedMessage()); 

    }finally { 
     if (result != null) { 
      result.close(); 
      result = null; 
     } 
    } 

     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      Log.e(TAG, e.getMessage()); 
     } 
    } 
} 
}).start(); 

DataBaseHelper:

public class DataBaseHelper extends SQLiteOpenHelper { 

    private static final int DATABASE_VERSION = 1; 
    public static final String DATABASE_NAME = "YadProjectDB.db"; 
    public static final String SMS_TABLE_NAME = "sms"; 
    public static final String SMS_COLUMN_PHONE_NUMBER = "number"; 
    public static final String SMS_COLUMN_SMS_TEXT = "message"; 

    public static final String BLACK_LIST_TABLE_NAME = "blackList"; 
    public static final String BLACK_LIST_COLUMN_ID = "id"; 
    public static final String BLACK_LIST_COLUMN_PHONE_NUMBER = "number"; 

    private final String TAG = "DataBaseHelper"; 

    public DataBaseHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 

    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     String command = "CREATE TABLE " 
       + SMS_TABLE_NAME 
       + "(" 
       + SMS_COLUMN_PHONE_NUMBER + " TEXT," 
       + SMS_COLUMN_SMS_TEXT + " TEXT," 
       + ")"; 
     try { 
      db.execSQL(command); 
     }catch (Exception e) { 
      Log.e(TAG, "err->" + e.getMessage()); 
     } 

     command = "CREATE TABLE " 
       + BLACK_LIST_TABLE_NAME 
       + "(" 
       + BLACK_LIST_COLUMN_PHONE_NUMBER + " TEXT," 
       + ")"; 
     try { 
      db.execSQL(command); 
     }catch (Exception e) { 
      Log.e(TAG, "err->" + e.getMessage()); 
     } 
    } 

    public boolean insertToSms(String number, String message, String fileName, Integer uploadFlag, Integer blackList, Integer pictureFlag) 
    { 
     final SQLiteDatabase db = this.getWritableDatabase(); 
     ContentValues contentValues = new ContentValues(); 
     contentValues.put(SMS_COLUMN_PHONE_NUMBER, number); 
     contentValues.put(SMS_COLUMN_SMS_TEXT, message); 
     try { 
      db.insert(SMS_TABLE_NAME, null, contentValues); 
      return true; 
     }catch (Exception e) { 
      Log.e(TAG, "err->" + e.getMessage()); 
      return false; 
     } 
    } 

    public Cursor getData(String query){ 
     final SQLiteDatabase db = getReadableDatabase(); 
     Cursor res = null; 
     try { 
      res = db.rawQuery(query, null); 
      res.moveToFirst(); 
      return res; 
     }catch (Exception e) { 
      Log.e(TAG, "err->" + e.getMessage()); 
      if (res != null) { 
       res.close(); 
       res = null; 
      } 
     } 
     return null; 
    } 
} 
+0

co dokładnie chcesz osiągnąć? – pskink

+1

Przyczyna tych wyjątków i znajdź problem. – exshinigami

+0

ok, dlaczego wykonujesz iterację po kursorze? – pskink

Odpowiedz

8

Jest to wygląda na ten sam problem jak SQLite Android Database Cursor window allocation of 2048 kb failed

Twój błąd mówi: „Otwarte kursory”

Odpowiedź na powyższe pytanie wyjaśnia:

Najczęściej przyczyną tego błędu są dla zamknięte kursory. Upewnij się, że zamykasz wszystkie kursory po ich użyciu (nawet w przypadku błędu).

Cursor cursor = null; 
try { 
    cursor = db.query(... 
    // do some work with the cursor here. 
} finally { 
    // this gets called even if there is an exception somewhere above 
    if(cursor != null) 
     cursor.close(); 
} 
+0

Jak widać zamykam kursor odpowiednio – exshinigami

+1

A co z kursorami w innych miejscach w aplikacji? Możesz przeciekać je gdzie indziej. –

+0

Używam tego samego kodu w innych wątkach, ale z inną logiką. a co z innymi wyjątkami? – exshinigami