Android尝试读取空对象引用

时间:2015-04-28 07:01:13

标签: java android nullpointerexception adapter

我希望从JSON内容创建一个列表。这是我的适配器代码:

public class AnswersAdapter extends ArrayAdapter<Answer> {

    static Context context;
    static int layoutResourceId;
    Answer data[] = null;

    public AnswersAdapter(Context context, int layoutResourceId, Answer[] data) {
        super(context, layoutResourceId, data);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.data = data;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        AnswerHolder holder = null;
        if(row == null)
        {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);
            holder = new AnswerHolder();
            holder.txtTitle = (TextView)row.findViewById(R.id.answerText);
            holder.txtTitle2 = (TextView)row.findViewById(R.id.answerAuthor);
            holder.txtTitle3 = (TextView)row.findViewById(R.id.answerVotes);
            row.setTag(holder);
        }
        else
        {
            holder = (AnswerHolder)row.getTag();
        }
        Answer hold = data[position];
            holder.txtTitle.setText(Html.fromHtml(hold.text));
            holder.txtTitle2.setText(hold.author);
            holder.txtTitle3.setText(hold.votes);

        return row;
    }

    static class AnswerHolder
    {
        TextView txtTitle;
        TextView txtTitle2;
        TextView txtTitle3;
    }
}

我正面临这个错误:

  

java.lang.NullPointerException:尝试从空对象引用上的字段'java.lang.String com.example.shivam.stackoverflow.Answer.text'中读取

在这一行

holder.txtTitle.setText(Html.fromHtml(hold.text));

2 个答案:

答案 0 :(得分:1)

您的data数组包含空值。这是NPE的直接原因,因为对于某些职位,hold最终为null。如果你测试它,你将避免使用NPE,但是(正如你在评论中指出的那样)你的适配器将不会正常运行。您不能简单地忽略具有null数据值的行。

顺便说一句,您应该删除data成员字段。数组引用已由ArrayAdapter超类保存。只要您使用getItem(position),就可以使用data[position]。虽然这不会解决NPE问题,但它会简化一些事情,如下所示。

您有几种选择:

  1. 找出data的某些条目开始为null的原因并消除根本问题。但是,datanull个条目可能是正常的(在适配器的上下文之外)。
  2. 修改getView方法,将holder中的视图设置为某些指示“数据缺失”的特定值 - 可能是空白,也许是“无数据”消息。 (换句话说,不要简单地跳过所有处理。这就是导致空行和重复行组合的原因。)
  3. 修改构造函数以消除null中的data条目。这将导致更短的列表。一些代码可能是:

    public AnswersAdapter(Context context, int layoutResourceId, Answer[] data) {
        super(context, layoutResourceId, trimmedData(data));
        this.layoutResourceId = layoutResourceId;
        this.context = context;
    }
    
    /**
     * Copy data to a new array that has no nulls.
     */
    private static Answer[] trimmedData(Answer[] data) {
        Answer[] result = new Answer[data.length];
        int n = 0;
        for (Answer a : data) {
            if (a != null) {
                result[n++] = a;
            }
        }
        if (n < data.length) {
            result = Arrays.copyOf(result, n, Answer.class);
        }
        return result;
    }
    

    但是,如果您需要保持ListView位置与原始data数组之间的对应关系,则可能会导致代码中的其他位置出现问题。

  4. 另一方面:您可以取消getItemId()方法; ArrayAdapter中的默认实现完全相同。

答案 1 :(得分:-7)

只需更改此行.....

Answer data[] = null;

Answer[] data = null;