1

私はListViewを持っています。これはカーソルからデータを受け入れます。レコードのカーソルの位置は、View.setTag()を介して格納されるため、ユーザーのイベントに応じて取得できます。アクティビティライフサイクルvsビューライフサイクル:NPEを回避する方法は?

public class OrderActivity extends Activity { 

    private ListView list; 
    private CursorAdapter adapter; 
    private SQLiteDatabase database; 

    public void onResume() { 
    database = new Database(this).getWriteableDatabase(); 
    // query the db and store the position of the cursor 
    // as the tag while binding the view in the overridden 
    // CursorAdapter.bindView() 
    adapter = new SimpleCursorAdapter(/* code here */); 
    list.setAdapter(adapter); 
    } 

    public void onPause() { 
    adapter.changeCursor(null); 
    database.close(); 
    } 

    private void onClickRowDumpOrder(View row) { 
    int newPosition = (Integer) row.getTag(); 
    Cursor cursor = adapter.getCursor(); 
    int originalPosition = cursor.getPosition(); // Throws NPE 

    cursor.moveToPosition(newPosition); 
    Log.v("tag", "Description: " + cursor.getString(0)); 

    // restore the cursor 
    cursor.moveToPosition(originalPosition); 
    } 

} 

私は活動のライフサイクルの間に/自由なリソースを割り当てるために、私の活動のインスタンスフィールドでのデータベースとアダプタを格納します。私は、新しいデータベースonResumeを作成し、それを閉じます。残念ながら、私は上記の擬似コードで説明された行にNPEがスローされたことをユーザーから多く報告しましたが、再現できません。

(私はを経由してXMLレイアウトでこれを設定) cursornullですが、それは、クリックイベントへのコールバックだから方法 onClickRowDumpOrderのみ、 onResume後に呼び出すことができる場合、私はこれが可能であるか疑問に思うようです

何か間違っていますか? cursorがnullになるのはどのようなAPIの誤用ですか?カーソルとアダプターがアクティビティー・ライフ・サイクルに収まるように意図されていることを説明する文書がありますか?

UPDATE

私はXMLファイルでを取り除くと、手動SimpleCursorAdapter.bindView内でリスナーを設定しました。リークを避けるために、私は自分のカスタムAbsListView.RecycleListenerと私のアクティビティの(私はreclaimViews(List<View>)ですべてのビューを取得します)のリスナーを削除します。これはバグを修正するようですが、ここで私の説明です。新しいビューは、私の活動が最初に起動したとき、それは属性

  • インスタンス#を解析する際に、私の活動の
  • インスタンス#1は、ビューのコンストラクタで、その特定のビューに対してOnClickListenerとして設定されて膨張さ

    1. 1がフォアグラウンドを離れるので、onPause()はカーソルをnullに設定します。ビューやアクティビティのどちらもガベージコレクションのマークが付いていないため、このアクティビティはViewのリスナーであることに注意してください。これは、Androidクラスの一部のキャッシュで参照されていることを意味します。
    2. 自分のアクティビティのインスタンス#2が作成され、そのリストビューは幾分リサイクル既に作成されたビューです。データは正しく表示されますが、このビューにはリスナーとしての古いアクティビティ(ヌルカーソル付き)があります。
    3. ユーザーがビューをクリックすると、インスタンス#1ハンドラがコールされますがnullカーソルがあります。 NPE

    この説明は現実的ですが、Androidクラスで関連するコードが見つかりませんでした(AbsListView.RecycleBinにキャッシュがありますが、ListView自体は再利用されません)。さらに、私はこのバグを再現することはできませんでした。私は最後の2日で報告は受けませんでした(通常、私は数日に数十を得ます)。私の前提を検証できるAndroidスタックには?

  • +0

    NPEを使用しないで、ポートレート/風景の間で電話機を何回も素早く回転できますか? – techiServices

    +0

    はい、とにかくポートレートモードしか許可されていないので、これは私のアプリとは関係ないので、ユーザがデバイスを回転させるとアクティビティは破壊されません – Raffaele

    +0

    カーソルを作成するために使用しているコードを投稿してください –

    答えて

    0

    この方法で試すことができます。 if (cursor.moveToFirst()) { for (int i = 0; i < cursor.getCount(); i++) { cursor.moveToPosition(i); } }

    +0

    私の問題は、カーソルがonClickRowの内部でnullであることです。 – Raffaele

    0

    アクティビティライフサイクルの間違った位置にカーソルを作成していると思います。ListView sampleは、onResume()にあるものをonCreate()に置きます。私はそれが必ずしも有害であるかどうかはわかりませんが、そうである必要のないことを再現しているかもしれません。

    +0

    これは最適化ですが、その問題とは何ですか?もちろん、カーソルonPauseを解除してもNPEは起動しませんが、間違った修正**があります。注意深く私の質問(特に自分自身の修正を加えた更新)を読んだ場合、 'android:onClick'を使うと、古いアクティビティがリスナーとしてリークするようです。私はあなたがこれを調査して、私の修正がうまくいくかどうかを伝えなければならないと思うが、あなたの提案はそのエラーだけを強調するだろう。残念ながら私はあなたに与える再現可能なケースがありません:( – Raffaele

    関連する問題