BaseAdapter在调用notifyDataSetChanged()时崩溃。

3
我已经创建了一个自定义的ListView和Adapter,通过继承BaseAdapter实现。每当我尝试在适配器上调用notifyDataSetChanged()方法时,程序会因为NullPointerException而崩溃。
以下是我的ListView和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);

每当通过网络接收到新数据时,我会在AsyncTask中执行以下操作以更新listview:

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)

谢谢你


иҜ·дҪ иғҪеҗҰеҲҶдә«дҪ зҡ„AsyncTaskе®һзҺ°е‘ўпјҹдҪ зҡ„convListжҲҗе‘ҳжҳҜеңЁе“ӘйҮҢе®ҡд№үзҡ„пјҹе®ғеә”иҜҘжҳҜдёҖдёӘзұ»зә§еҸҳйҮҸгҖӮ - rekaszeru
空指针异常本身的堆栈跟踪也可能很有用。 - Stephan
AsyncTask和堆栈跟踪已添加到帖子中。 - user718581
你说得对,AsyncTask应该可以工作,我唯一能想到的出错原因是你的dataAdapter为空。你的堆栈跟踪可能有多个“Caused by”子句,它们指示了你代码内部NullPointerException的起点。如果你能提供这些信息就更好了。在此之前,请尝试在断点处检查onProgressUpdate(String... i)方法中访问的dataAdapter是否有值。谢谢! - rekaszeru
"((BaseAdapter) ((ListView)findViewById(R.id.conv_list)).getAdapter()).notifyDataSetChanged();" 这段精确的代码我尝试执行了,但列表仍然没有更新。其余的重写方法几乎相同。有什么想法/建议吗? - CoDe
显示剩余3条评论
1个回答

6

与其

dataAdapter.notifyDataSetChanged(); 

你应该尝试

((ListView)findViewById(R.id.conv_list)).getAdapter().notifyDataSetChanged(); 

你的 MessageAdapter dataAdapter 成员变量也是私有的吗?我假设它是私有的,否则你应该会得到编译错误。
所以如果是私有的,请确保你初始化了它,在你的 onCreate 方法中不要再声明一个同名的局部变量(这样你的私有类成员将保持为 null!)。
你代码中的这行代码表明你将一个本地变量 adapter 赋值给你的 ListView
MessageAdapter dataAdapter = new MessageAdapter(this, convList);

1
太棒了!将dataAdapter.notifyDataSetChanged()更改为((BaseAdapter) ((ListView)findViewById(R.id.conv_list)).getAdapter()).notifyDataSetChanged();起作用了。是的,看起来dataAdapter只存在于onCreate()方法中--糟糕!将其变成类变量也解决了这个问题。谢谢你的帮助。 - user718581
不客气。此外,因为您的快速回复和清晰明了的问题,我给您加一分。 - rekaszeru
2
我正在从baseadapter内部执行此notifyDataSetChanged(),那么我需要做什么... - kamal_tech_view
this.notifyDataSetChaged(); 我并不认为你需要在 BaseAdapter 实现中调用它的原因。 - rekaszeru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接