時不時用戶例外得到以下(我自己不能複製):java.lang.IllegalStateException - 爲什麼? (安卓,ListAdapter)
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(2131165209, class android.widget.ListView) with Adapter(class com.tfd.mobile.TfdSearch.TfdSearch$SearchList$PagesListAdapter)]
at android.widget.ListView.layoutChildren(ListView.java:1567)
at android.widget.AbsListView.onTouchModeChanged(AbsListView.java:2093)
at android.view.ViewTreeObserver.dispatchOnTouchModeChanged(ViewTreeObserver..java:591)
at android.view.ViewRoot.ensureTouchModeLocally(ViewRoot.java:2023)
at android.view.ViewRoot.ensureTouchMode(ViewRoot.java:2007)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1775)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4633)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)
我找不到爲什麼會發生。我使用線程,但主線程中的所有底層數據更改。我總是調用_adapter.notifyDataSetChanged();數據更改後。請幫幫我!這是我的代碼:
private class SearchList extends LinkedList<PageInfo>
{
private static final long serialVersionUID = 1L;
private PagesListAdapter _adapter;
public PagesListAdapter getAdapter()
{
return _adapter;
}
public SearchList(ListView listView)
{
super();
_adapter = new PagesListAdapter(activity, this);
listView.setAdapter(_adapter);
}
private void getSuggestions(final String typedText)
{
showProgressVisibility(true);
new Thread(new Runnable() {
public void run() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
final String[] sugg = TfdMode.getMode().getSuggestions(typedText);
activity.runOnUiThread(new Runnable() {
public void run() {
if (sugg != null)
{
clear();
for (String s: sugg) {
add(new PageInfo(s, PageInfo.PAGE_SUGGESTION, null));
}
}
_adapter.notifyDataSetChanged();
showProgressVisibility(false);
}
});
}
}).start();
}
public void refresh(final String typedText)
{
if (typedText.length() >= 3)
{
// use suggestions (separate thread)
getSuggestions(typedText);
}
else
{
// use recent
clear();
for (PageInfo p: TfdMode.getMode().recentManager.pages) {
if (p.text.startsWith(typedText)) add(p);
}
if (size() == 0 && typedText.length() > 0)
getSuggestions(typedText); // if no recent - use suggestions
else
_adapter.notifyDataSetChanged();
}
}
public class PagesListAdapter extends ArrayAdapter<PageInfo> {
private LayoutInflater mInflater;
public PagesListAdapter(Context context, List<PageInfo> objects) {
super(context, R.layout.bookmarks_item, R.id.bookmark_title, objects);
mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final PageInfo b = getItem(position);
View row = convertView == null ? mInflater.inflate(R.layout.bookmarks_item, null) : convertView;
TextView title = (TextView) row.findViewById(R.id.bookmark_title);
ImageView img = (ImageView) row.findViewById(R.id.bookmark_img);
ImageView del = (ImageView) row.findViewById(R.id.bookmark_img_del);
del.setVisibility(View.GONE);
title.setText(b.text);
int iconId = b.getIconResId();
if (iconId != -1)
{
img.setImageResource(iconId);
img.setVisibility(View.VISIBLE);
}
else
img.setVisibility(View.INVISIBLE);
return row;
}
}
};
數據更改的唯一地方 - 「刷新」方法調用時。它總是從主線程調用。爲什麼它仍然發生?幫幫我!
什麼時候發生java.lang.IllegalStateException EXCEPTION? ** ** 當我明確從非UI線程中執行「刷新」的方法,我在_adapter.notifyDataSetChanged的時刻得到另一個異常(CalledFromWrongThreadException)()調用:
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): FATAL EXCEPTION: Thread-27
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): at android.view.ViewRoot.checkThread(ViewRoot.java:2837)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): at android.view.ViewRoot.invalidateChild(ViewRoot.java:619)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:645)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): at android.view.ViewGroup.invalidateChild(ViewGroup.java:2505)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): at android.view.View.invalidate(View.java:5192)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): at android.view.View.setFlags(View.java:4569)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): at android.view.View.setVisibility(View.java:3083)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): at com.tfd.mobile.TfdSearch.TfdSearch.showProgressVisibility(TfdSearch.java:315)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): at com.tfd.mobile.TfdSearch.TfdSearch.access$0(TfdSearch.java:313)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): at com.tfd.mobile.TfdSearch.TfdSearch$SearchList.getSuggestions(TfdSearch.java:783)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): at com.tfd.mobile.TfdSearch.TfdSearch$SearchList.refresh(TfdSearch.java:823)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): at com.tfd.mobile.TfdSearch.TfdSearch$8$1.run(TfdSearch.java:443)
10-12 13:20:29.057: ERROR/AndroidRuntime(24746): at java.lang.Thread.run(Thread.java:1096)
你在哪裏調用刷新? – Cristian
我打電話刷新: 1. editText的TextChangeListener。 2. setDisplayMode方法。此方法從代碼周圍的不同位置調用,但在調用刷新之前很多UI對象都會觸及此方法,因此如果從非UI線程調用它,在「刷新」獲得調用機會之前它會失敗更多。 –