我有可分页的ListView,它的行在向下滚动时异步加载,有时候应用程序崩溃了.它不会发生在
Android 2.3.3上,但确实发生在Android 4.0及更高版本上.
这是我的堆栈跟踪:
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,result,lastFetchedPage); } setOnRefreshListener(properOnRefreshListener); } catch (NASAException e) { DialogHandler.handleError(mContext,e.getMessage(mContext)); } finally { removeFooterView(footerView); actualTask = null; } } }; actualTask.executeCached(activity,request);
解决方法
你可以尝试在ListView中添加这样的东西:
@Override protected void layoutChildren() { try { super.layoutChildren(); } catch (IllegalStateException e) { ZLog.e(LOG,"This is not realy dangerous problem"); } }
如果添加headerview或footerview ListView,并且当你notifyDataSetChanged()时,它会将mItemCount更改为真实适配器的项目数,但右侧将返回添加了headercount和footercount的假itemcount: