ListViews に IllegalStateExceptions に関する投稿が多数あることは知っていますが、解決策はありませんでした。うまくいけば、誰かが私が間違っていることを見つけるのを手伝ってくれるでしょう。
どうしたの?
SharedPreferences の特定のプロパティが更新されると、ListView のデータを提供する ArrayList を更新し、ListView に通知します。IllegalStateException はAndroid 4 でのみスローされます(Android 2.3 では発生しません) 。ListView 内の項目数が変化し、更新時にユーザーがスクロールしている場合です。
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(); を呼び出す ...)。
私はあなたの助けと提案に非常に感謝しています.