我知道在ListViews中有很多关于IllegalStateExceptions的帖子,但没有解决方案适合我。希望有人能帮助我找出我做错了什么。
发生了什么事?
当我的SharedPreferences中的某个属性被更新时,我更新了为ListView提供数据的ArrayList,并通知ListView。当ListView中的项目数量发生变化且用户正在滚动时,仅在Android 4 (从未在Android 2.3上)抛出IllegalStateException 更新发生时。
IllegalStateException异常
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(); ...)。 / p>
我将非常感谢您的帮助和建议,感谢任何帮助!