2011-08-21 39 views
0

我有一个ListView,它可能包含数千行,由CursorAdapter生成。任何时候只能看到八行左右的行。我有报告说,启动这个视图可能需要很多秒,并可能导致ANR(强制关闭)。ListView.setListAdapter很慢

我在做后台线程中的数据库查询。我已验证我的适配器中的newViewbindView仅被称为可见行数。

一旦显示列表,实际上下滚动列表非常快。

延迟是在调用ListView.setListAdapter,它必须在UI线程上运行。为什么这似乎取决于结果集中的总行数,而不是实际显示的行数(更小)?有什么办法可以优化它吗?

这个问题被问到几年前in this thread。我希望得到一些新的见解和潜在解决方法的更具体的例子。

UPDATE

我曾尝试用CommonsWare's EndlessAdapter来解决这个问题。我使用我的数据库查询中的LIMIT子句将初始查询限制为(比如说)20行,并且增加此限制,并在每次点击列表底部时重新提交查询。

(顺便说一句,我还没有发现追加只是新成果,以现有的光标的方式,所以每次我增加LIMIT值,然后重新取整幅达新光标的新限制。)

奇怪的是,此解决方法似乎并未改善执行初始setListAdapter调用所需的时间。当我在只包含20行的数据集上运行它时,对setListAdapter的调用非常快。当我在一个包含数百行的数据集上运行它时,仅限于返回20,它需要一秒以上。

更新2

通过强制查询在后台线程用一个简单的getCount()执行,由CommonsWare的建议,我已经治好了UI线程的初始堵塞上启动活动。但是,从儿童活动返回到此活动时,UI仍然被阻止。默认情况下,ListActivity似乎要重新在UI线程上运行查询。

我已经通过删除onStop()中的适配器并在onStart()中重新创建它。因此,无论我们在活动堆栈中移动的方向如何,查询总是在后台执行。

回答

4

我做的数据库查询在后台线程

如果你在后台做的是电话query()rawQuery(),查询并没有真正执行。当您第一次尝试使用Cursor(例如,getCount())时,它将被延迟执行。因此,在后台执行查询的正确方法是在后台线程中输入rawQuery()后跟类似getCount(),以确保查询真正执行。

当我在一个包含数百行的数据集上运行它,但仅限于返回20行时,它需要一秒多的时间。

关闭袖口,这表明速度问题不是读取结果所需的时间,而是首先计算结果。

+0

谢谢,在后台线程中对'getCount()'的简单调用具有完全理想的效果。 –