java.lang.IllegalStateException:适配器的内容发生了变化,但ListView控件....召notifydatasetchanged inspite() [英] java.lang.IllegalStateException: The content of the adapter has changed but ListView.... inspite of calling notifydatasetchanged()

查看:236
本文介绍了java.lang.IllegalStateException:适配器的内容发生了变化,但ListView控件....召notifydatasetchanged inspite()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是应遵循的后台线程(异步任务)?更新listactivty内容的最佳实践

1)我打电话在 notifyDataSetChanged(),以尽快更新适配器我操纵适配器的内容,但同时用户滚动或单击列表中的还是我的应用程序强制关闭。以prevent任何指针,这将是非常有益的。

logcat的:
java.lang.IllegalStateException:适配器的内容发生了变化,但ListView控件没有收到通知

2)exaclty我应该更新listactivity的内容是什么?在doInBackground()或onProgressUpdate()里面呢?

3),当用户点击列表项是经历常规崩溃。因此,将在后台运行期间禁止在listactivty click事件解决这个问题?如果是这样我不知道如何删除或动态设置项点击听众的listactivity。请指示我的了。

4)我不认为后台异步任务执行期间阻止所有UI交互是解决问题的唯一途径。我知道有这样一个简单的方法,但需要一些帮助。

先谢谢了。

这是我的onCreate ...

 保护无效的onCreate(捆绑savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.fa);tvStatus =(的TextView)findViewById(R.id.tvStatus); 适配器=新SimpleAdapter(
        本,
        mostPopularList,
        R.layout.list_item,
        新的String [] {标题,作者,意见,日期},
        新的INT [] {R.id.textView1,R.id.textView2,R.id.textView4,R.id.textView3});
        // populateList();
        setListAdapter(适配器);
  }

我的异步任务...

 私有类LongOperation扩展的AsyncTask<弦乐,太虚,字符串> {          @覆盖
          保护字符串doInBackground(字符串... PARAMS){
        // code增加新listactivty项目
          }          @覆盖
          保护无效onPostExecute(字符串networkStatus){
            adapter.notifyDataSetChanged();
          }          @覆盖
          在preExecute保护无效(){          }          @覆盖
          保护无效onProgressUpdate(虚空......值){           }
          }

logcat的:

我很少在非法状态的异常太...无法重现它。将张贴的logcat如果我再次遇到它。

 致命异常:主要
java.lang.IndexOutOfBoundsException:无效指数7,大小为4
    在java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
    在java.util.ArrayList.get(ArrayList.java:311)
    在android.widget.SimpleAdapter.bindView(SimpleAdapter.java:147)
    在android.widget.SimpleAdapter.createViewFromResource(SimpleAdapter.java:126)
    在android.widget.SimpleAdapter.getView(SimpleAdapter.java:114)
    在android.widget.AbsListView.obtainView(AbsListView.java:1294)
    在android.widget.ListView.makeAndAddView(ListView.java:1727)
    在android.widget.ListView.fillDown(ListView.java:652)
    在android.widget.ListView.fillGap(ListView.java:623)
    在android.widget.AbsListView.trackMotionScroll(AbsListView.java:2944)
    在android.widget.AbsListView.onTouchEvent(AbsListView.java:2065)
    在android.widget.ListView.onTouchEvent(ListView.java:3315)
    在android.view.View.dispatchTouchEvent(View.java:3766)
    在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:897)
    在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    在com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1671)
    在com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
    在android.app.Activity.dispatchTouchEvent(Activity.java:2086)
    在com.android.internal.policy.impl.PhoneWindow $ DecorView.dispatchTouchEvent(PhoneWindow.java:1655)
    在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    在com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1671)
    在com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
    在android.app.Activity.dispatchTouchEvent(Activity.java:2086)
    在com.android.internal.policy.impl.PhoneWindow $ DecorView.dispatchTouchEvent(PhoneWindow.java:1655)
    在android.view.ViewRoot.handleMessage(ViewRoot.java:1785)
    在android.os.Handler.dispatchMessage(Handler.java:99)
    在android.os.Looper.loop(Looper.java:123)
    在android.app.ActivityThread.main(ActivityThread.java:4627)
    在java.lang.reflect.Method.invokeNative(本机方法)
    在java.lang.reflect.Method.invoke(Method.java:521)
    在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:868)
    在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)


解决方案

  

2)exaclty我应该更新listactivity的内容是什么?在doInBackground()或onProgressUpdate()里面呢?


onProgressUpdate()或内部onPostExecute(),因为既然你改变内容它可能需要一些时间doInBackground()和呼叫异步任务调用你的

  @覆盖
          保护无效onPostExecute(字符串networkStatus){
            adapter.notifyDataSetChanged();
          }


  

3),当用户点击列表项是经历常规崩溃。因此,将在后台运行期间禁止在listactivty click事件解决这个问题?如果是这样我不知道如何删除或动态设置项点击听众的listactivity。请指导我对了。


这不是一个解决方案。你只需要更新您的UI线程数据集。 (不加载内容,从旧只需更新到一个新的)。例如:

 私有类LongOperation扩展的AsyncTask<弦乐,太虚,字符串> {      @覆盖
      保护列表与LT;弦乐> doInBackground(字符串... PARAMS){
           清单<串GT;项目= loadUpdatedDataset(PARAMS);
           返回的物品;
      }      @覆盖
      保护无效onPostExecute(列表<串GT; loadedItems){
        updateAdapterDataset(loadedItems);
        adapter.notifyDataSetChanged();
      }      @覆盖
      在preExecute保护无效(){      }      @覆盖
      保护无效onProgressUpdate(虚空......值){       }
      }

What are the best practices to be followed to update the contents of a listactivty by a background thread (Async Task) ?

1) Am calling the notifyDataSetChanged() to update the adapter as soon as i manipulate the contents of the adapter but still my app force closes while the user scrolls or click on the list. Any pointers to prevent this would be very helpfull.

Logcat: java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification.

2) Where exaclty should i update contents of the listactivity ? inside the doInBackground() or onProgressUpdate()?

3) Am experiencing regular crashes when the user clicks the list item. So will disabling click events on the listactivty during the background operation solve the problem ? If so am not sure how to remove or set item click listeners dynamically to the listactivity. Please instruct me on the too.

4) I dont think blocking all ui interactions during the background async task execution is the only way to solve the problem. I know there is a simple way of doing this but need some help.

Thanks in advance.

This is my onCreate...

protected void onCreate(Bundle savedInstanceState) {    
super.onCreate(savedInstanceState);
setContentView(R.layout.fa);

tvStatus=(TextView) findViewById(R.id.tvStatus);

 adapter = new SimpleAdapter(
        this,
        mostPopularList,
        R.layout.list_item,
        new String[] {"title","author","views","date"},
        new int[] {R.id.textView1,R.id.textView2,R.id.textView4,R.id.textView3});
        //populateList();


        setListAdapter(adapter);
  }

My async task...

          private class LongOperation extends AsyncTask<String, Void, String> {

          @Override
          protected String doInBackground(String... params) {
        // code for adding new listactivty items 
          }      

          @Override
          protected void onPostExecute(String networkStatus) {
            adapter.notifyDataSetChanged();
          }

          @Override
          protected void onPreExecute() {

          }

          @Override
          protected void onProgressUpdate(Void... values) {

           }
          }

Logcat:

i rarely the the illegalstate exception too... not able to reproduce it. will post the logcat if i come across it again.

FATAL EXCEPTION: main
java.lang.IndexOutOfBoundsException: Invalid index 7, size is 4
    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
    at java.util.ArrayList.get(ArrayList.java:311)
    at android.widget.SimpleAdapter.bindView(SimpleAdapter.java:147)
    at android.widget.SimpleAdapter.createViewFromResource(SimpleAdapter.java:126)
    at android.widget.SimpleAdapter.getView(SimpleAdapter.java:114)
    at android.widget.AbsListView.obtainView(AbsListView.java:1294)
    at android.widget.ListView.makeAndAddView(ListView.java:1727)
    at android.widget.ListView.fillDown(ListView.java:652)
    at android.widget.ListView.fillGap(ListView.java:623)
    at android.widget.AbsListView.trackMotionScroll(AbsListView.java:2944)
    at android.widget.AbsListView.onTouchEvent(AbsListView.java:2065)
    at android.widget.ListView.onTouchEvent(ListView.java:3315)
    at android.view.View.dispatchTouchEvent(View.java:3766)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:897)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1671)
    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
    at android.app.Activity.dispatchTouchEvent(Activity.java:2086)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1655)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1671)
    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
    at android.app.Activity.dispatchTouchEvent(Activity.java:2086)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1655)
    at android.view.ViewRoot.handleMessage(ViewRoot.java:1785)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:4627)
    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:868)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)

解决方案

2) Where exaclty should i update contents of the listactivity ? inside the doInBackground() or onProgressUpdate()?

Inside onProgressUpdate() or inside onPostExecute() because it could take some time since you change content in doInBackground() and call async task calls your

          @Override
          protected void onPostExecute(String networkStatus) {
            adapter.notifyDataSetChanged();
          }

3) Am experiencing regular crashes when the user clicks the list item. So will disabling click events on the listactivty during the background operation solve the problem ? If so am not sure how to remove or set item click listeners dynamically to the listactivity. Please instruct me on the too.

It is not a solution. You just need update your dataset on UI thread. (Not load content, just update from old to a new one). For example

private class LongOperation extends AsyncTask<String, Void, String> {

      @Override
      protected List<String> doInBackground(String... params) {
           List<String> items = loadUpdatedDataset(params);
           return items;
      }      

      @Override
      protected void onPostExecute(List<String> loadedItems) {
        updateAdapterDataset(loadedItems);
        adapter.notifyDataSetChanged();
      }

      @Override
      protected void onPreExecute() {

      }

      @Override
      protected void onProgressUpdate(Void... values) {

       }
      }

这篇关于java.lang.IllegalStateException:适配器的内容发生了变化,但ListView控件....召notifydatasetchanged inspite()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆