1

我有一个ListView其中来自光标适应数据。光标的记录位置通过View.setTag()存储,因此可以响应用户事件进行检索。活动生命周期与视图生命周期:如何避免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被列在上面伪代码的概述中,但我无法再现它。

似乎cursornull,但我不知道这是可能的,如果方法onClickRowDumpOrder只能onResume之后调用,因为它回调到Click事件(我通过设置这个在XML布局)

我做错了什么? API错误导致cursor为空?是否有一些文档描述了游标和适配器如何适应活动生命周期?

UPDATE

我在我的XML文件中摆脱和手动设置内部SimpleCursorAdapter.bindView听众。为了避免泄密,我删除了听者无论是在我的自定义AbsListView.RecycleListener,在我活动的(我检索与reclaimViews(List<View>)所有视图)。这似乎解决了这个错误,这是我的解释。

  1. 新论充气时,我的活动第一次启动
  2. 实例#我的活动1设置为OnClickListener在视图的构造特定视图,当它解析属性
  3. 实例# 1离开前景,因此onPause()将光标设置为null。请注意,此活动仍是View的侦听器,因为视图和活动都未标记为垃圾收集。这意味着它们在某些缓存引用在Android类
  4. 我的活动实例#2被创建,它的列表视图有些回收已创建的视图。数据显示正确的,但这种观点仍然有老年活动(用一个空指针)作为听者
  5. 当用户点击我的看法
  6. ,例如#1处理程序被调用,但它有一个空指针。这将导致NPE

这种解释是现实的,但我没有发现Android的类相关的代码(存在AbsListView.RecycleBin缓存,但ListView控件本身不重复使用)。此外,我从来没有能够重现这个错误,我只是觉得我的修复工作,因为在过去两天我没有收到任何报告(通常我每天得到几十个)

你知道任何代码在可以验证我的假设的Android堆栈中?

+0

因此,您可以在不使用NPE的情况下多次快速在人像/风景之间旋转手机吗? – techiServices

+0

是的,无论如何,这与我的应用程序无关,因为它只允许纵向模式,所以当用户旋转设备时,活动不会被破坏 – Raffaele

+0

请发布您用于创建光标的代码 –

回答

0

你可以试试这个方法。 if (cursor.moveToFirst()) { for (int i = 0; i < cursor.getCount(); i++) { cursor.moveToPosition(i); } }

+0

我的问题是游标在null内onClickRow – Raffaele

0

我认为你在Activity生命周期中的错误点创建了游标。ListView sampleonCreate()放在onResume()中。我不知道这有害,但你可能正在重新创造一些不需要的东西。

+0

这将是一个优化,但这个问题有什么关系?当然,如果我没有取消设置光标“onPause”,它不会触发NPE,但这是**错误的修复**。如果您仔细阅读我的问题(特别是使用我自己修复的更新),看起来旧活动在使用'android:onClick'时会作为监听器泄漏。我想你应该调查一下,并告诉我/为什么我的修复工作,但你的建议只会欺骗错误。不幸的是,我没有可重复的情况下给你:( – Raffaele