Search code examples
javaandroidlistviewnullpointerexceptionfooter

NullPointerException on addFooterView() on some devices


First, let me explain my code: When the user clicks a button, this code is executed:

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

When the Async has finished, this code is executed:

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

This is where things go wrong though. Because on some devices I'm getting a NullPointerException on this line:

mMyListView.addFooterView(mMyFooterView);

Here's the 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)

The weird thing is that I only get this exception when the user clicks the button that fetches the data the second time. The first time everything goes smooth: the listView is shown and the footer is added. The second time though, I get this exception on some devices.

Does anyone know how to fix this?


Solution

  • if (mMyList.size() > 0){
        mMyListView.addFooterView(mMyFooterView);
    }    
    

    It appears that you want to remove the footer when there is no data. While I don't know how to prevent this error with your current code, I recommend a different tactic.

    • If both data sets will use a footer then don't remove it to add it again (you can still change it if you want different content.)
    • When the data set is empty hide the entire ListView with setVisibilty(View.GONE).

    But the error log and source code are clear, calling setAdapter(null) doesn't unregister the internal DataSetOberver which throws the NPE in GingerBread:

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