2

我知道 ListViews 中有很多关于 IllegalStateExceptions 的帖子,但没有任何解决方案适合我。希望有人可以帮助我找出我做错了什么。

这是怎么回事?

当我的 SharedPreferences 中的某个属性更新时,我会更新为 ListView 提供数据的 ArrayList,并通知 ListView。IllegalStateException仅在 Android 4 上引发(从不在 Android 2.3 上),当ListView 中的项目数量发生变化并且用户在更新发生时滚动时。

非法状态异常

java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131165193, class android.widget.ListView) with Adapter(class com.example.view.StatusActivity$StatusAdapter)]
at android.widget.ListView.layoutChildren(ListView.java:1545)
at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4082)
[...]

编码

这是相关活动的最小版本。ListView 更新是从 onSharedPreferenceChanged 触发的,我还确保在 UI 线程上执行更新(与 IllegalStateException 所建议的相反)。

public class StatusActivity extends Activity implements OnSharedPreferenceChangeListener {

    private ArrayList<Status> stati;
    private ListView listview;
    private SharedPreferences prefs;
    private StatusAdapter adapter;

    private static final int TYPE_STATUS = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_status);
        prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        prefs.registerOnSharedPreferenceChangeListener(this);

        listview = (ListView) findViewById(R.id.list);

        adapter = new StatusAdapter();
    }

    public void onResume(){
        super.onResume();
        updateList();
    }

    public void updateList(){
        StatusDAO.initialize(this);
        stati = (ArrayList<Status>) StatusDAO.readAll();
        adapter.notifyDataSetChanged();

        listview.invalidateViews();
        listview.refreshDrawableState();
    }

    private class StatusAdapter extends BaseAdapter {

        private Status current;

        public int getCount() {
                return stati.size();
        }

        public Object getItem(int position) {
                return stati.get(position);
        }

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

        public int getItemViewType(int position) {
                return TYPE_STATUS;
        }

        public int getViewTypeCount() {
                return 1;
        }

        public boolean isEnabled(int position) {
            return false;
        }

        public View getView(int position, View convertView, ViewGroup parent) {

            if(convertView == null) {
                    final LayoutInflater inflater = LayoutInflater.from(StatusActivity.this);
                    final int layout = R.layout.item_status;
                    convertView = inflater.inflate(layout, parent, false);
            } 


            // [..]

            return convertView;
        }

    }

    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        if(key.equals(Configuration.PREF_LOADINGSTATUS)){   
            runOnUiThread(new Runnable() {
                public void run() {
                    updateList();
                }
            });
        }
    }

}

我不知道如何解决这个问题,因为我已经尝试了互联网上建议的所有内容(确保数据集的更新发生在 UI 线程上;调用 notifyDataSetChanged(); ...)。

我将非常感谢您的帮助和建议,感谢任何帮助!

4

0 回答 0