5

我正在製作一個使用數據庫的Kiosk應用程序。該應用程序始終在前臺運行。該應用程序有許多線程使用一個共享的DataBaseHelper實例。應用5或6小時後完美的作品,但大部分時間裏,我遇到這些異常,然後應用程序崩潰:2048 kb的光標窗口分配失敗。 #打開遊標= 1(#這個proc = 1打開的遊標)

E/DataBaseHelper:光標窗口分配2048 kb的失敗。 #打開 遊標= 1(#遊標打開此PROC = 1)

E/CursorWindow:無法分配CursorWindow '/data/user/0/com.kios.frm/databases/YadProjectDB.db' 的 大小2097152由於錯誤-24。

E/SQLiteLog:(14)在

E/SQLiteLog的[00bb9c9ce4] 30192線無法打開文件:(14)語句中止在16:[SELECT數量從SMS LIMIT 5]無法打開數據庫文件

E/SQLiteQuery:異常:無法打開數據庫文件(代碼14);
查詢:SELECT數量從SMS LIMIT 5

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

我正確關閉了遊標,但仍然得到這些例外。那些例外是什麼?這些例外的原因是什麼?

MainActivity

private DataBaseHelper db = null; // Global  

MainActivity onCreate方法:

​​

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

你到底想要什麼來實現呢? – pskink

+1

這些例外的原因,並找到問題 – exshinigami

+0

好吧,爲什麼你迭代光標? – pskink

回答

8

這是看起來相同的問題SQLite Android Database Cursor window allocation of 2048 kb failed

你的錯誤說:「打開的遊標」

在上述問題的答案解釋它:

大多數情況下此錯誤的原因是不關閉遊標。確保使用後關閉所有遊標(即使在出現錯誤的情況下) 。

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

正如你所看到的,我正在關閉遊標 – exshinigami

+1

而你的應用程序中其他地方的遊標又如何?你可能會把它們泄漏到別處。 –

+0

我在其他線程中使用相同的代碼,但具有不同的邏輯。其他例外情況如何? – exshinigami