33

このコードで「非アクティブ化または閉じられていないカーソルのファイナライズ」エラーが発生します。このコードは、リストビューを埋めるために使用されます。

これは致命的ではないエラーであるため、クラッシュは発生せず、すべて正常に機能しているようです。しかし、エラーは気に入らないです。

このコードの最後でカーソルを閉じると、リストビューは空のままになります。onStopでカーソルを閉じると、同じエラーが発生します。

これを修正するにはどうすればよいですか?

private void updateList() { 
        DBAdapter db = new DBAdapter(this); 
        db.open(); 
            //load all waiting alarm 
            mCursor=db.getTitles("state<2"); 
            setListAdapter(new MyCursorAdapter(this, mCursor)); 
            registerForContextMenu(getListView()); 
            db.close(); 
        } 


error : 


E/Cursor  ( 2318): Finalizing a Cursor that has not been deactivated 
or closed. database = /data/data/xxxxxxxxxxxxxxx.db, table = alerts, 
query = SELECT _id, alert_id, 
E/Cursor  ( 2318): 
android.database.sqlite.DatabaseObjectNotClosedException: Application 
did not close the cursor or database 
object that was opened here 
E/Cursor  ( 2318):      at 
android.database.sqlite.SQLiteCursor.<init>(SQLiteCursor.java:210) 
E/Cursor  ( 2318):      at 
android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDr­iver.java: 
53) 
E/Cursor  ( 2318):      at 
android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.j­ava: 
1345) 
E/Cursor  ( 2318):      at 
android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java­: 
1229) 
.... 
.... 
4

9 に答える 9

26

またはを閉じるCursorと、そのメッセージは表示されません。もう一度お試しください。または、クエリからを取得した後に呼び出すと、Android が自動的に を閉じます。onStop()onDestroy()startManagingCursor()CursorCursor

于 2010-06-18T11:41:21.893 に答える
13

スコット、

私はあなたと同じ問題に遭遇しました。「db.close()」などのデータベースを閉じる前に、「mCursor.close()」などのカーソルが最初に閉じられていることを確認してください。

そのようです:

private void updateList()
{ 
    DBAdapter db = new DBAdapter(this);
    db.open();

    //load all waiting alarm
    mCursor=db.getTitles("state<2"); 
    setListAdapter(new MyCursorAdapter(this, mCursor)); 
    registerForContextMenu(getListView()); 

    // Let's close the cursor.
    mCursor.close();
    db.close(); 
} 

カーソルを閉じた場合、リスト ビューは空のままであると述べました。情報をクラスに渡してコピーし (メモリを割り当て)、カーソルを閉じることをお勧めします。

于 2010-09-08T20:10:43.810 に答える
2

クエリがカーソルを返すと、実際にはカーソルの最初のレコードの「前」に配置されます。アダプタは最初の要素で「getItem」を実行しようとするため、カーソルがどの要素にも配置されていないため失敗します。

ベースアダプタでは、getViewsでcursorMoveToPositionを実行します。これにより、movefirstの必要がなくなるようです。

于 2011-02-19T04:56:35.477 に答える
1

作成中のカーソル オブジェクトを閉じます。

カーソル オブジェクトを作成し、SQLite テーブルのトラバースが完了したら、使用後に閉じます。このカーソルのクローズにより、logcat での例外が防止されます。

開いたままのカーソルのファイナライズに関連する例外は発生しません。

これにより、アプリケーションの同じ問題が修正されました。

于 2012-12-28T07:01:09.543 に答える
1

startManagingCursor() は推奨される方法ではなくなったため、使用しないでください。この問題は、ファイナライザーがこのオブジェクトに到達するまでにカーソル/DB 接続がまだ閉じられていないために発生します。ローダーがカーソルを管理できるようにするか、すべてのカーソル/DB/SQLiteOpenHelper接続を自分で追跡し、それらの後にクリーンアップすることで、これを回避できます。

ローダーを使用するのはかなり面倒で、たとえばリスト ビューと連動させるには多くの可動部分が必要です。一方、カーソルとデータベース接続を追跡すると、人的エラーが発生しやすくなります。カーソル/DB オブジェクトの数が少ない場合は、後者のソリューションをお勧めします。そうでない場合は、ローダーに接続を処理させます。

于 2012-09-30T12:47:58.350 に答える
0

私もカーソルを閉じる際に問題を抱えていました:

  • リスト ビューのアダプタを設定した直後にカーソルを閉じると、データが表示される前にカーソルが閉じます。

  • 廃止されたため、startManagingCursor を使用してカーソルを管理することはできません。

  • startManagingCursor の新しい cursorLoader の置き換えはやり過ぎのようです。

  • 提案どおりにカーソルの位置を移動しても機能しませんでした。

  • タスクをアクティビティの内部クラスにし、アクティビティの onDestroy メソッドでカーソルを閉じると、常に機能するわけではありません。

  • タスクをアクティビティの内部クラスにして、アクティビティの onStop メソッドでカーソルを閉じるとうまくいっているようです。

また、カーソルを閉じる前にデータベースと sqlite オープン ヘルパーを閉じることができることもわかりました。リスト ビューのアダプターを設定した直後にそれらを閉じることもできます。データは引き続き表示されます。

于 2011-12-01T02:05:42.883 に答える
0

ちょうど同じ問題があり、あなたに知らせようと思った - 念のため....

誤ってフェッチ ルーチンを 2 回呼び出してしまい、最初の呼び出しの結果のカーソルが「失われました」。これがエラーの原因でした。

于 2011-11-02T10:50:21.183 に答える
0

私はこの問題に2日間苦労しました。データベースクエリから返されたカーソルをリストアダプターに直接渡すサンプルコードを動作させようとしていました-暫定アダプターはありません。ListAdapterに渡す前にカーソルで「moveToFirst()」を呼び出すまで、動作を拒否しました-空白の画面を表示しただけです。図に行く!これをコメントアウトすると、壊れます。

私が経験したのと同じ闘争を人々を救うために、これを共有しようと思った.

なぜこれがそうなのか、誰かが光を当てることができれば、私はそれを感謝します. カーソルを適切に実行するために、これまでカーソルで moveToFirst を呼び出す必要はありませんでした。

于 2010-12-11T12:44:20.123 に答える
0

startManagingCursor(カーソル);

これで問題が解決しました

于 2012-02-01T20:23:12.020 に答える