【问题标题】:NullPointerException on addFooterView() on some devices某些设备上 addFooterView() 上的 NullPointerException
【发布时间】:2013-02-21 15:12:07
【问题描述】:

首先,让我解释一下我的代码: 当用户单击按钮时,将执行以下代码:

mMyListView.removeFooterView(mMyFooterView);
mMyListView.setAdapter(null);
//Fetch some data in an AsyncTask

Async 完成后,将执行以下代码:

if (mMyList.size() > 0){
    mMyListView.addFooterView(mMyFooterView);
}    
MyListAdapter myListAdapter = new MyListAdapter(this, mMyList);
mMyListView.setAdapter(myListAdapter);

这就是问题所在。因为在某些设备上,我在这一行收到 NullPointerException:

mMyListView.addFooterView(mMyFooterView);

这是 StackTrace:

java.lang.NullPointerException
at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:778)
at android.widget.ListView.addFooterView(ListView.java:387)
at android.widget.ListView.addFooterView(ListView.java:402)
at com.augustinianum.augustinianum.ManualCheckActivity.showScheduleChanges(ManualCheckActivity.java:84)
at com.augustinianum.augustinianum.ManualCheckActivity.access$1(ManualCheckActivity.java:81)
at com.augustinianum.augustinianum.ManualCheckActivity$CheckScheduleChange.onPostExecute(ManualCheckActivity.java:192)
at com.augustinianum.augustinianum.ManualCheckActivity$CheckScheduleChange.onPostExecute(ManualCheckActivity.java:1)
at android.os.AsyncTask.finish(AsyncTask.java:417)
at android.os.AsyncTask.access$300(AsyncTask.java:127)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3687)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
at dalvik.system.NativeStart.main(Native Method)

奇怪的是,当用户第二次点击获取数据的按钮时,我才得到这个异常。第一次一切顺利:显示 listView 并添加页脚。但是第二次,我在某些设备上遇到了这个异常。

有谁知道如何解决这个问题?

【问题讨论】:

  • 已全局声明mMyListView并在onCreate..上初始化它?
  • @Pragnani 是的,我在我的类块中定义了它,并使用 findViewById() 将其填充到 onCreate() 中。
  • 以下细节很难追查问题,如果你添加一些代码会有所帮助。
  • @Pragnani 好吧,我的代码很长,所以我认为在这里粘贴我的整个代码不是一个好主意。如果您需要我的代码的额外部分,请询问。
  • @Sam 最低 API 级别为 3。它崩溃的设备运行 Android 2.3。

标签: java android listview nullpointerexception footer


【解决方案1】:
if (mMyList.size() > 0){
    mMyListView.addFooterView(mMyFooterView);
}    

您似乎想在没有数据时删除页脚。虽然我不知道如何使用您当前的代码来防止此错误,但我建议采用不同的策略。

  • 如果两个数据集都将使用页脚,则不要删除它以再次添加它(如果需要不同的内容,您仍然可以更改它。)
  • 当数据集为空时,用setVisibilty(View.GONE) 隐藏整个ListView。

但是错误日志和源代码很清楚,调用setAdapter(null) 不会取消注册在 GingerBread 中抛出 NPE 的内部 DataSetOberver:

at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:778)
at android.widget.ListView.addFooterView(ListView.java:387)

【讨论】:

  • 但是如果我在页脚已经存在时调用 addFooterView() ,它不会也抛出异常吗?
  • 在澄清我的想法之前,我做了几个假设......我想确保它适用于你想要的。除非它是空的,否则您的 ListView 是否总是有页脚?
  • 你改变过mMyFooterView的布局或内容吗?
  • 好的,不要在更改适配器时添加和删除页脚,而是添加一次,当适配器为空时调用mMyListView.setVisibility(View.GONE);。稍后当您向mMyList 添加数据时,使mMyListView 再次可见并且页脚已经存在。
  • 好的,非常感谢您的大力帮助!!我将尝试一下,并在我开始工作后立即将您的答案标记为已接受!谢谢!!
【解决方案2】:

这是我解决它的方法:

当用户点击按钮时,这段代码被执行:

mMyListView.setVisibility(View.INVISIBLE);
//Fetch some data in an AsyncTask

Async 完成后,将执行以下代码:

mMyListView.setVisibility(View.VISIBLE);
if (mMyList.size() > 0){
    mMyListView.removeFooterView(mMyFooterView);
    mMyListView.addFooterView(mMyFooterView);
}    
MyListAdapter myListAdapter = new MyListAdapter(this, mMyList);
mMyListView.setAdapter(myListAdapter);

这段代码完美运行。

不过,我会接受 Sam 的回答,因为他很好地解释了抛出异常的原因。此外,多亏了他,我可以弥补这个解决方案。所以为山姆+1! :)

【讨论】:

  • 我很惊讶mMyListView 允许您在设置适配器后添加页脚,但我很高兴您找到了解决方案!
  • @Sam 我对此进行了一些研究,看来您可以在setAdapter() 之后调用addHeaderView()/addFooterView(),只要您之前至少调用过其中一种方法。很高兴知道我认为!
猜你喜欢
  • 2014-01-08
  • 2013-05-28
  • 2018-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多