【问题标题】:java.lang.IllegalStateException: The content of the adapter has changed(Signalr)java.lang.IllegalStateException:适配器的内容已更改(Signalr)
【发布时间】:2015-08-10 09:56:17
【问题描述】:

在我的 android 应用程序中显示以下异常。我正在使用单个列表视图和单个适配器。我正在使用 2 个不同的回调函数(来自 signalr)来更新列表视图,但一次只有一个。

异常显示:

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. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131361927, class android.widget.ListView) with Adapter(class com.indus.TAP.PanelDisplay$LogAdaptor)]
08-04 11:42:34.624: E/AndroidRuntime(7133):

代码:

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        LogAdaptor log = (LogAdaptor) lvLog.getAdapter();
        log.notifyDataSetChanged();
        lvLog.post(new Runnable() {
            @Override
            public void run() {
                lvLog.smoothScrollToPosition(lvLog.getCount());
            }
        });
    }
});

【问题讨论】:

  • 你打电话给notifyDataSetChanged()了吗?
  • 是的,我在“runOnUiThread”内部调用了
  • @FarooqArshed 此代码将作为信号器回调方法的结果每秒执行一次。
  • 您应该发布lvLog 代码。这看起来像是一个时间问题,notifyDataSetChanged() 在更改数据的 post 调用之前被调用。为了验证这个假设,您可以将notifyDataSetChanged() 移动到smoothScrollToPosition 之后并进行测试
  • @rangarajb2005,请查看stackoverflow.com/questions/30846096/…

标签: android


【解决方案1】:

有两个关键点:

  1. 确保在模型更改时调用 notifyDataSetChanged 方法
  2. 如果您在后台线程中更改模型,请使用广播通知数据更改

【讨论】:

  • 每 1 秒会有一个新数据(数据变化),现在我正在使用一个处理程序来更改数据集,这个处理程序是作为信号器回调的结果。使用处理程序更改列表视图数据集时是否有任何问题
【解决方案2】:

如果你的 SignalR 是服务,你可以这样尝试

    @Override
    public void onCreate() {
        super.onCreate();
        mHandler = new Handler(Looper.getMainLooper());
    }

    private startSignalR(...) {
      ...
      mHub.on("broadcastMessage",
                new SubscriptionHandler1<String>() {
                    @Override
                    public void run(final String msg) {
                        ...
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                // Update adapter and call notifyDataSetChanged here                                 
                            }
                        });
                    }
                }
                , String.class);
      ...
   }

更新: 在 notifyDataSetChanged 后尝试延迟执行,例如:

adapter.notifyDataSetChanged();                    
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
     @Override
     public void run() {
         ...
         ...                            
     }
}, 1000);

【讨论】:

  • 不使用信号器作为服务,只需创建一个自定义集线器连接类并使用它。
  • 我刚刚更新了我的答案,你可以这样尝试
  • 每1秒会有一个新数据(数据变化-会得到5到10行数据),所以当我尝试postDelayed时,我丢失了一些数据
  • 你运行了吗?您可以将延迟减少到 100 毫秒或更短
  • 是的,我只试了一秒钟。无论如何,我会尝试使用更小的时间值。
猜你喜欢
  • 2015-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多