我正在申请。我想在asynctask中从服务器获取信息后添加更多项目,并使用我定义的对象进行保存。
这是我的代码。

EventCheck.java

private void put(final Event event){
    if(event!=null){
        events = push(events,event);
        Log.d("no after= ",Integer.toString(event.getNo()));
        if(!firsttime){
            context.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    adapter = new Eventlist(context,getEvents());
                    adapter.setNotifyOnChange(true);
                    list.setAdapter(adapter);
                }
            });
            firsttime=true;
        }else{
            context.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.d("no = ",Integer.toString(event.getNo()));
                    Log.d("title = ",event.getTitle());
                    Log.d("description = ",event.getDescription());
                    adapter.add(event);
                    adapter.notifyDataSetChanged();
                }
            });
        }
    }
}


adapter.java

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.provider.Settings;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class Eventlist extends ArrayAdapter<Event>{
    private final Activity context;
private final Event[] events;
private final String[] title;
private final String[] description;
public Eventlist(Activity context,Event[] events) {
    super(context, R.layout.list_event, events);
    this.context = context;
    this.events = events;
    this.title = new String[events.length];
    this.description = new String[events.length];
    for(int i=0;i<events.length;i++){
        title[i]=events[i].getTitle();
        description[i] = events[i].getDescription();
    }
};
@Override
public View getView(int position, View view, ViewGroup parent) {
    LayoutInflater inflater = context.getLayoutInflater();
    View rowView = inflater.inflate(R.layout.list_event, null, true);
    TextView txtContent = (TextView) rowView.findViewById(R.id.belisttitle);
    String line = new StringBuilder().append(position+1).append(" .").append(" ").append(title[position]).append(System.getProperty ("line.separator")).toString();
    line = new StringBuilder().append(line).append(description[position]).toString();
    txtContent.setText(line);
    return rowView;
}

}


它引发以下异常:

10-04 16:07:56.855: E/AndroidRuntime(14835): java.lang.UnsupportedOperationException
10-04 16:07:56.855: E/AndroidRuntime(14835):    at java.util.AbstractList.add(AbstractList.java:404)
10-04 16:07:56.855: E/AndroidRuntime(14835):    at java.util.AbstractList.add(AbstractList.java:425)
10-04 16:07:56.855: E/AndroidRuntime(14835):    at android.widget.ArrayAdapter.add(ArrayAdapter.java:179)
10-04 16:07:56.855: E/AndroidRuntime(14835):    at com.xxx.xxx.Eventcheck$2.run(Eventcheck.java:257)
10-04 16:07:56.855: E/AndroidRuntime(14835):    at android.os.Handler.handleCallback(Handler.java:733)
10-04 16:07:56.855: E/AndroidRuntime(14835):    at android.os.Handler.dispatchMessage(Handler.java:95)
10-04 16:07:56.855: E/AndroidRuntime(14835):    at android.os.Looper.loop(Looper.java:136)
10-04 16:07:56.855: E/AndroidRuntime(14835):    at android.app.ActivityThread.main(ActivityThread.java:5140)
10-04 16:07:56.855: E/AndroidRuntime(14835):    at java.lang.reflect.Method.invokeNative(Native Method)
10-04 16:07:56.855: E/AndroidRuntime(14835):    at java.lang.reflect.Method.invoke(Method.java:515)
10-04 16:07:56.855: E/AndroidRuntime(14835):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
10-04 16:07:56.855: E/AndroidRuntime(14835):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:611)
10-04 16:07:56.855: E/AndroidRuntime(14835):    at dalvik.system.NativeStart.main(Native Method)


第257行是adapter.add(event)行
我想问我的代码有什么问题吗?
任何人都可以帮助我找出问题所在吗?

最佳答案

我想问我的代码有什么问题吗?


您的代码天生没有错。简短的答案是您遇到了特定于Java的怪癖。忍受我:

您要调用的ArrayAdapter构造函数的源代码如下所示:

public ArrayAdapter(Context context, int textViewResourceId, T[] objects) {
    init(context, textViewResourceId, 0, Arrays.asList(objects));
}


最后一个参数(您提供的数组)不会发生什么:通过调用ArrayList将其“转换”为Arrays.asList(objects)

现在,实际上可以通过查看the documentation for this method call找到答案:


  返回指定数组中对象的列表。列表的大小无法修改,即不支持添加和删除,但是可以设置元素。设置元素会修改基础数组。


基本上发生的是将您传入的数组转换为固定大小的列表(如果在运行时对代码进行断点,则应该看到一个UnmodifiableCollection实例-注意:与不可变的实例不同)。您不能添加或删除任何项目,而只能设置项目(它不会更改列表大小,因为它会替换现有项目),尽管默认情况下ArrayAdapter类不会公开后者的操作。

最简单的解决方案是调用等效的ArrayAdapter构造函数,该构造函数自己使用ArrayList而不是数组:

public ArrayAdapter(Context context, int resource, List<T> objects)


这将需要对当前代码进行一些小的更改,但是数组和列表的使用非常相似。另外,请记住在您的适配器中实现ViewHolder / RowWrapper模式-那里有很多示例。最后,将标题和描述存储在单独的数组中并没有任何好处,这与面向对象的编程和封装的思想相矛盾。只需让对象“拥有”这些属性并使用getter方法访问它们即可。

//编辑:

这是一些示例代码,说明对ArrayAdapter的更改,包括有关如何使用ViewHolder模式的信息。我直接在浏览器中输入了此内容,因此请务必注意任何类型/语法错误。

您仍然必须稍微更改put()方法,以便它可以处理事件列表而不是数组,但是我将由您自己决定。在线上确实有大量示例可以帮助您。

public class Eventlist extends ArrayAdapter<Event>{

    private static final String LINE_SEPARATOR = System.getProperty ("line.separator");

    public Eventlist(Context context, List<Event> events) {
        super(context, R.layout.list_event, events);
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        View rowView = view;
        ViewHolder holder;

        if (rowView == null) {
            holder = new ViewHolder();
            LayoutInflater inflater = LayoutInflater.from(getContext());
            rowView = inflater.inflate(R.layout.list_event, null, true);
            holder.txtContent = (TextView) rowView.findViewById(R.id.belisttitle);
            rowView.setTag(holder);
        } else {
            holder = (ViewHolder) rowView.getTag();
        }

        Event event = getItem(position);
        StringBuilder line = new StringBuilder(position+1)
            .append(" . ")
            .append(event.getTitle())
            .append(LINE_SEPARATOR)
            .append(event.getDescription());
        holder.txtContent.setText(line);

        return rowView;
    }

    static class ViewHolder {
        private TextView txtContent;
    }

}

关于java - adapter.add(event)抛出java.lang.UnsupportedOperationException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26190960/

10-12 03:59