I have created a custom listview and adapter by extending BaseAdapter. Every time I try and call notifyDataSetChanged() on the adapter, the program crashes with a NullPointerException.
This is my code for creating the listview and adapter:
private ArrayList<MessageItem> convList = new ArrayList<MessageItem>();
// setup list view
ListView list = (ListView)findViewById(R.id.conv_list);
MessageAdapter dataAdapter = new MessageAdapter(this, convList);
list.setAdapter(dataAdapter);
list.setVisibility(View.VISIBLE);
I try and update the listview by doing this within an AsyncTask everytime new data is received over the network:
protected class ConversationTask extends AsyncTask<Context, String, String>
{
@Override
protected String doInBackground(Context... arg0) {
for (;;) {
while (t_recv.messageQueue.isEmpty());
publishProgress(t_recv.messageQueue.remove(t_recv.messageQueue.size() - 1));
}
}
@Override
protected void onProgressUpdate(String... i)
{
convList.add(new MessageItem("Name", "Msg"));
dataAdapter.notifyDataSetChanged();
}
}
A NullPointerException occurs on calling notifyDataSetChanged(). If I remove this call, the listview will only update if I press the back button, or show/hide the keyboard (i'm guessing this somehow triggers an update). So... am I doing something wrong here?
The code for the adapter is below if you need it:
public class MessageAdapter extends BaseAdapter
{
private Context context;
private ArrayList<MessageItem> listMessage;
public MessageAdapter(Context context, ArrayList<MessageItem> listMessage) {
this.context = context;
this.listMessage = listMessage;
}
public View getView(int position, View convertView, ViewGroup viewGroup) {
MessageItem entry = listMessage.get(position);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.message, null, false);
}
TextView tvName = (TextView) convertView.findViewById(R.id.tvName);
tvName.setText(entry.getName());
TextView tvMsg = (TextView) convertView.findViewById(R.id.tvMsg);
tvMsg.setText(entry.getMsg());
return convertView;
}
public int getCount() {
return listMessage.size();
}
public Object getItem(int position) {
return listMessage.get(position);
}
public long getItemId(int position) {
return position;
}
}
Each item in the list is a 'MessageItem' as shown below:
public class MessageItem
{
private String name;
private String msg;
public MessageItem(String name, String msg) {
this.name = name;
this.msg = msg;
}
// Getter 开发者_如何学编程methods
public String getName() { return name; }
public String getMsg() { return msg; }
}
Also, the error is:
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): FATAL EXCEPTION: main
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): java.lang.NullPointerException
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): at com.client.Conversation.appendMessage(Conversation.java:129)
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): at com.client.Conversation.access$2(Conversation.java:122)
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): at com.client.Conversation$ConversationTask.onProgressUpdate(Conversation.java:170)
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): at com.client.Conversation$ConversationTask.onProgressUpdate(Conversation.java:1)
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:432)
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): at android.os.Handler.dispatchMessage(Handler.java:99)
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): at android.os.Looper.loop(Looper.java:143)
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): at android.app.ActivityThread.main(ActivityThread.java:5068)
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): at java.lang.reflect.Method.invokeNative(Native Method)
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): at java.lang.reflect.Method.invoke(Method.java:521)
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
04-21 13:56:30.762: ERROR/AndroidRuntime(30024): at dalvik.system.NativeStart.main(Native Method)
Thank you
Instead of
dataAdapter.notifyDataSetChanged();
you should try
((ListView)findViewById(R.id.conv_list)).getAdapter().notifyDataSetChanged();
Is your MessageAdapter dataAdapter
member also a private variable? I assume it is, otherwise you should have gotten compile errors.
So if it is, make sure that you initialize that one, don't have inside your onCreate
method an other declaration with the same name (this way your private class member would remain null!).
This line in your code suggests that you assign a local variable adapter to your ListView
:
MessageAdapter dataAdapter = new MessageAdapter(this, convList);
精彩评论