2013-03-07 8 views
7

ページング可能なListViewがあり、その行がスクロール中に非同期にロードされていて、アプリがクラッシュすることがあります。 Android 2.3.3では起こっていませんが、Android 4.0以降では起こります。ここでページングクラッシュのあるAndroidリストビュー

は私のスタックトレースです:

03-07 15:23:02.450: D/AndroidRuntime(1545): Shutting down VM 
03-07 15:23:02.450: W/dalvikvm(1545): threadid=1: thread exiting with uncaught exception (group=0x40ccb930) 
03-07 15:23:02.455: E/AndroidRuntime(1545): FATAL EXCEPTION: main 
03-07 15:23:02.455: E/AndroidRuntime(1545): 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(2131099953, class com.ui.PaginableListView) with Adapter(class android.widget.HeaderViewListAdapter)] 
03-07 15:23:02.455: E/AndroidRuntime(1545):   at android.widget.ListView.layoutChildren(ListView.java:1544) 
03-07 15:23:02.455: E/AndroidRuntime(1545):   at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4042) 
03-07 15:23:02.455: E/AndroidRuntime(1545):   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749) 
03-07 15:23:02.455: E/AndroidRuntime(1545):   at android.view.Choreographer.doCallbacks(Choreographer.java:562) 
03-07 15:23:02.455: E/AndroidRuntime(1545):   at android.view.Choreographer.doFrame(Choreographer.java:531) 
03-07 15:23:02.455: E/AndroidRuntime(1545):   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735) 
03-07 15:23:02.455: E/AndroidRuntime(1545):   at android.os.Handler.handleCallback(Handler.java:725) 
03-07 15:23:02.455: E/AndroidRuntime(1545):   at android.os.Handler.dispatchMessage(Handler.java:92) 
03-07 15:23:02.455: E/AndroidRuntime(1545):   at android.os.Looper.loop(Looper.java:137) 
03-07 15:23:02.455: E/AndroidRuntime(1545):   at android.app.ActivityThread.main(ActivityThread.java:5191) 
03-07 15:23:02.455: E/AndroidRuntime(1545):   at java.lang.reflect.Method.invokeNative(Native Method) 
03-07 15:23:02.455: E/AndroidRuntime(1545):   at java.lang.reflect.Method.invoke(Method.java:511) 
03-07 15:23:02.455: E/AndroidRuntime(1545):   at com.android.internal.os.ZygoteInit$MethodAnd 

それはおそらく、非常に役立つコードの一部ではありません。/

protected DataResponse doInBackground(IRequest... reqs) { 
    IRequest req = reqs[0]; 
    CancelStateHolder cancelStateHolder = new CancelStateHolder() { 
     @Override 
     public boolean isCancelled() { 
      return DataRequestTask.this.isCancelled(); 
     } 
    }; 

    if (cacheKey != null) { 
     try { 
      CacheDogpileProtector.getInstance().acquire(cacheKey); 
     } catch (InterruptedException e) { 
      cancel(true); 
      ZLog.printStackTrace(e); 
     } 
    } 

    reqExec.setParentTask(this); 
    DataResponse resp = reqExec.execute(req, cancelStateHolder, 
    cacheContext, cacheKey); 
    if (resp == null) { 
     Log.d(LOG, "resp == null"); 
    } 
    return resp; 
} 

@Override 
protected void onPostExecute(DataResponse result) { 
    super.onPostExecute(result); 
    ZLog.d(LOG, "override onPostExecute"); 
    try { 
     if (result.getJsonResponse() == null) { 
      ZLog.i(LOG, "json is NULL (probably connection problem) response text: " + result.getResponseText()); 
      throw new NASAException(R.string.exception_io); 
     } 
     ConsumptionStatus consumption = ConsumptionStatus.REQUEST_NOT_CONSUMED; 
     if (onZadaneRequestCompletedListener != null) { 
      consumption = onZadaneRequestCompletedListener.onZadaneRequestCompleted(PaginableListView.this, request, result); 
     } 

     switch (consumption) { 
      case REQUEST_CONSUMED: 
       break; 
      case REQUEST_UPDATE_METADATA: 
       wrapAndUpdate(result.getJsonResponse(), true); 
       break; 
      case REQUEST_NOT_CONSUMED: 
       wrapAndUpdate(result.getJsonResponse(), false); 
       break; 
     } 
     if (onZadaneRequestCompletedListener != null) { 
      onZadaneRequestCompletedListener.onZadaneRequestCompletedAfterWrap(PaginableListView.this, request, result, lastFetchedPage); 
     } 
     setOnRefreshListener(properOnRefreshListener); 
    } catch (NASAException e) { 
     DialogHandler.handleError(mContext, e.getMessage(mContext)); 
    } finally { 
     removeFooterView(footerView); 
     actualTask = null; 
    } 
} 

}; 
actualTask.executeCached(activity, cacheContext, request); 
+0

あなたRESUをロードしている:実際のアダプタの数が、右側はheadercountとfootercountを追加しました偽ITEMCOUNT個を返します。 'AsyncTask'または' Thread'を使用していますか? – MCeley

+0

*「あなたのアダプターの内容は、バックグラウンドスレッドではなくUIスレッドからのみ変更されていることを確認してください。」*あなたは理解できませんでしたか?私は失礼であることを意味しない、それは実際の質問です:) – m0skit0

+0

私はAsyncTaskを使用しています。 –

答えて

0

あなたのスタックトレースが言うように、あなたは、アダプタの内容を更新することはできませんバックグラウンドスレッドを使用します。 AsyncTaskを使用しているので、これを修正するのは簡単です。アダプタをdoInBackgroundにアップデートする代わりに、onPostExecuteにアップデートしてください。

これは次のようなものです。あなたがheaderviewまたはfooterviewのリストビューを追加し、あなたは()をnotifyDataSetChangedとき、それは項目にmItemCountを変更する場合は

@Override 
protected void layoutChildren() { 
    try { 
     super.layoutChildren(); 
    } catch (IllegalStateException e) { 
     ZLog.e(LOG, "This is not realy dangerous problem"); 
    } 
} 

@Override 
protected Object doInBackground(Object... params) { 
    Object results = getResults(); /* Replace with your own result fetching code */ 
    return results; 
} 

@Override 
protected void onPostExecute(Object result) { 
    super.onPostExecute(result); 
    /* Update your adapter here using the returned results. */ 
    myAdapter.addNewData(result); 
    myAdapter.notifyDataSetChanged(); 
} 
+0

私はすでにそれをしています:(それは問題を解決しません –