我通过扩展BaseAdapter创建了自定义列表视图和适配器。每次我尝试在适配器上调用notifyDataSetChanged()时,程序都会发生NullPointerException崩溃。
这是我创建listview和适配器的代码:
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);
每次通过网络收到新数据时,我都会尝试在AsyncTask中执行此更新列表视图:
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();
}
}
调用notifyDataSetChanged()时发生NullPointerException。如果我删除此调用,列表视图将仅在我按下后退按钮或显示/隐藏键盘时更新(我猜这会以某种方式触发更新)。所以......我在这里做错了吗?
如果需要,适配器的代码如下:
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;
}
}
列表中的每个项目都是'MessageItem',如下所示:
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; }
}
此外,错误是:
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)
谢谢
答案 0 :(得分:6)
而不是
dataAdapter.notifyDataSetChanged();
你应该试试
((ListView)findViewById(R.id.conv_list)).getAdapter().notifyDataSetChanged();
您的MessageAdapter dataAdapter
成员也是私有变量吗?我认为是,否则你应该得到编译错误。
所以,如果确实如此,请确保初始化那个,在onCreate
方法中没有一个具有相同名称的其他声明(这样你的私有类成员将保持为null!)。
代码中的这一行表明您为ListView
分配了一个本地变量适配器:
MessageAdapter dataAdapter = new MessageAdapter(this, convList);