2011-10-11 14 views
1

時間(私は自分自身がそれを再現することはできません):それはなぜ起こったか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; 
     } 
    } 


}; 

"刷新"メソッドが呼び出されるときにデータが変更される唯一の場所です。それは常にメインスレッドから呼び出します。それはなぜまだ起こるか???助けて!

例外的に例外はありますか?例外が発生しましたか?

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) 
+0

どこからリフレッシュしていますか? – Cristian

+0

私はからの更新を呼び出します: 1. editTextのTextChangeListener。 2. setDisplayModeメソッド。このメソッドはコードの周りのさまざまな場所から呼び出しますが、リフレッシュ前にこのメソッドに触れていたUIオブジェクトの多くは、UI以外のスレッドから呼び出された場合、「リフレッシュ」が呼び出される前にもっと失敗しました。 –

答えて

2

あなたがからリフレッシュを呼び出す必要があります:私は明示非UIスレッドから「リフレッシュ」メソッドを実行すると** **は、私が_adapter.notifyDataSetChanged()呼び出しの瞬間に別の例外(CalledFromWrongThreadException)を取得しますおそらくメインスレッドではないUIスレッドです。あなたは、UIスレッド上で何かを実行するためにこれを使用することができます:

Activity.runOnUiThread(Runnable) 

- >http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29

1

_adapter.notifyDataSetChanged();

これはUIスレッド上で実行する必要があります。ハンドラまたはrunOnUiThreadを使用

関連する問題