2013-07-05 26 views
12

私はアンドロイドアプリのSQLite3データベースで動作しています。私は、200k行と14列の既定のデータベースを読み込んだだけです。エントリーは単語です。すべての列のデータ型はテキストです。 11文字までの単語(ABANDONMENTなど)を検索すると問題なく動作します。しかし、12以上の場合(例えば、ABANDONMENTS)、アプリケーションがクラッシュします。ここでlogcatは、次のとおりです。CursorWindowを割り当てることができません

Could not allocate CursorWindow '//data//data//com.example.myapp//databases//database.sqlite' of size 2097152 due to error -12. 
threadid=11: thread exiting with uncaught exception (group=0x40adf9f0) 
FATAL EXCEPTION: Thread-2883 
android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=861 (# cursors opened by this proc=861) 
at android.database.CursorWindow.<init>(CursorWindow.java:104) 
at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198) 
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:162) 
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:156) 
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:161) 
at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:201) 
at com.example.myapp.MainActivity.query(MainActivity.java:815) 
at com.example.myapp.MainActivity$2.run(MainActivity.java:356) 
at java.lang.Thread.run(Thread.java:856) 

コード:

query = "select * from words where col_1 = \"" + (myWord)+ "\";"; 
cursor = database.rawQuery(query, null); 
if (cursor != null)           
    cursor.moveToFirst(); // line 815 
if (!cursor.isAfterLast()) { 
    do { 
     for (i = 1; i < cursor.getColumnCount(); i++) { 
      temp = cursor.getString(i); 
      //other stuff 
     } 
    } while (cursor.moveToNext()); 
    cursor.close(); 
} 

ので、エラーが何を意味し、なぜアプリがクラッシュしますか?

+1

完全なコードが役立ちます。 !cursor.isAfterLast()の代わりにcursor.moveToNext()を呼び出さないのはなぜですか? –

+0

完全なアプリケーションコードは1000行です。 cursor.isAfterLastは、カーソルがすべての結果を移動したかどうかを確認するために使用されます。 –

+0

whileループ内でカーソルを閉じていますか? –

答えて

12

私はループ内で渋滞していました。そしてループの内側でカーソルを閉じて、外側ではなく、問題を解決しました。

3

Androidカーソルはすべてのクエリ結果をメモリに読み込み、そのデータに対して1 MBの制限があります。

この制限が適用された理由は、この量のデータがモバイルデバイスでアプリを低速で実行する可能性があるからです。

あなたは、可能であれば必要があります。

  • はなく、あなたのコードではなく、SQLでの計算を行います。
  • 必要なデータのみをクエリします(SELECT *は使用せず、必要な列のみを取得し、WHEREフィルタを使用します)。
  • 小さな部分でデータを読み込みます。
+0

それはできません。すべての行はテーブル内で一意です。したがって、クエリでは1つの結果しか得られません。 –

+0

あなたは確かに複数のレコードを取得しています。同等の 'SELECT COUNT(*)... 'の結果は何ですか? –

18

エラー-12はカーソルリークを意味します。 Pls次のように閉じてみてください:

try {....} finally { cursor.close();} 
関連する問題