Android 什么';这是更新适配器的最佳实践方式;什么是基础数据?

Android 什么';这是更新适配器的最佳实践方式;什么是基础数据?,android,Android,我在更新适配器的基础列表时遇到了一个非法状态异常(可能是ArrayAdapter或BaseAdapter的扩展,我不记得了)。我现在没有或者不记得异常的文本,但是它说明了列表内容更改的效果,而适配器没有收到更改通知 此列表/可能/从UI线程(主线程)以外的其他线程更新。更新此列表(添加项目)后,我调用notifyDataSetChanged。问题似乎是适配器或附加到适配器的ListView在调用此方法之前尝试更新自身。发生这种情况时,将抛出IllegalStateException 如果在更新之

我在更新适配器的基础列表时遇到了一个非法状态异常(可能是ArrayAdapter或BaseAdapter的扩展,我不记得了)。我现在没有或者不记得异常的文本,但是它说明了列表内容更改的效果,而适配器没有收到更改通知

此列表/可能/从UI线程(主线程)以外的其他线程更新。更新此列表(添加项目)后,我调用notifyDataSetChanged。问题似乎是适配器或附加到适配器的ListView在调用此方法之前尝试更新自身。发生这种情况时,将抛出IllegalStateException

如果在更新之前将ListView的可见性设置为GONE,然后再次设置为VISIBLE,则不会发生错误。但这并不总是可行的

我在某个地方读到,您不能从另一个线程修改它的底层——这似乎限制了MVC模式,就像这个特定的列表一样,我想添加来自不同线程的项。我假设只要调用notifyDataSetChanged(),我就安全了——适配器在调用此方法之前不会重新访问底层列表,但情况似乎并非如此

我想我要问的是,从UI以外的线程更新底层列表是否安全?此外,如果我想修改适配器中的数据,我是否要修改基础列表或适配器本身(通过其add()等方法)。通过适配器修改数据似乎是错误的

我在另一个网站上遇到了一个帖子,来自一个似乎与我有类似问题的人:(这是我抓住可见性的地方。消失了。可见的想法)

为了让您更好地了解我的特定问题,我将介绍一下如何设置我的列表、适配器等

我有一个名为Queue的对象,它包含LinkedList。队列扩展了Observable,当通过其方法将内容添加到其内部列表时,我调用setChanged()和notifyListeners()。此队列对象可以从任意数量的线程中添加或删除项目

我有一个包含适配器的“队列视图”活动。此活动在其onCreate()方法中向我的队列对象注册一个观察者侦听器。在Observer的update()方法中,我在适配器上调用notifyDataSetChanged()

我添加了大量的日志输出,并确定当出现这个非法的StateException时,我的观察者回调从未被调用。因此,适配器似乎在观察者有机会通知其观察者之前就注意到了列表的更改,并调用我的方法通知适配器内容已更改

所以我想我要问的是,这是安装适配器的好方法吗?这是一个问题,因为我正在从UI线程以外的线程更新适配器的内容吗?如果是这种情况,我可能会想到一个解决方案(在创建队列对象时,为该UI线程提供一个处理程序,并使用该处理程序修改所有列表,但这似乎不合适)

我意识到这是一篇非常开放的文章,但我对此有点迷茫,希望能对我所写的内容发表评论

此列表/可能/更新自 UI以外的其他线程 螺纹(主)

那不行

我在某个地方读到了你读不到的东西 从中修改基础属性 另一个线程--这似乎是 限制MVC模式,如下所示 特定列表,我想添加项目 来自不同的线程

MVC与线程无关

更新文件是否安全 来自其他线程的基础列表 而不是用户界面

不可以。其他线程可以触发对适配器的更新(例如,通过
post()
),但对于当前连接到
列表视图的适配器,更新本身必须在主应用程序线程上处理

另外,如果我想修改 适配器中的数据,是否要修改 基础列表或适配器 自身(通过其add()等方法)。 通过适配器修改数据 这似乎是错误的

您可以通过
适配器
本身为
阵列适配器
修改
适配器
。您可以通过
CursorAdapter
的基础数据库/内容提供程序修改
适配器。其他适配器可能会有所不同

我有一个名为Queue的对象 包含链接列表。队列扩展 可观察的,当事物被添加时 通过其 方法,调用setChanged()和 notifyListeners()

您是否考虑过使用
LinkedBlockingQueue
,而不是实现自己的线程安全
队列

此活动,在其onCreate()中 方法,注册观察者侦听器 到我的队列对象。以观察员的名义 我调用的update()方法 适配器上的notifyDataSetChanged()

适配器
应在自身上调用
notifyDataSetChanged()
(如果更改是由适配器进行的),或由更改数据的实体(例如,对于
游标或适配器
)调用适配器。这就是MVC。
活动
既不知道也不关心数据模型何时更改

因此,适配器似乎注意到了 观察者发现之前列表的更改 通知观察员的机会,以及 调用我的方法来通知适配器 内容发生了变化

可能您使用的是
阵列适配器
,在这种情况下,所有这些额外的observer/notify内容都会妨碍您,因为这是为您处理的。您只需要在主应用程序线程上安排更新
ArrayAdapter

所以我想我要问的是 这是安装适配器的好方法吗

不特别,伊姆霍

这是因为我在更新吗 适配器的内容来自
Message msg;
msg = Message.obtain();
msg.what = MSG_IMG_SET;                     
mExtHandler.sendMessage(msg);
private Handler mImagesProgressHandler;

public void onCreate(Bundle bundle) {

    mImagesProgressHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {             
        case LoadImagesThread.MSG_IMG_SET:
            mArrayAdapter.setBitmapList(mImagesList);
            mArrayAdapter.notifyDataSetChanged();
            break;
        case LoadImagesThread.MSG_ERROR:
            break;
        }
        super.handleMessage(msg);
    }
};