Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/193.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android SQLite快速从游标获取所有数据_Android_Database_Performance_Sqlite_Cursor - Fatal编程技术网

Android SQLite快速从游标获取所有数据

Android SQLite快速从游标获取所有数据,android,database,performance,sqlite,cursor,Android,Database,Performance,Sqlite,Cursor,我正在处理我的一个应用程序中的性能问题。也许你们中的一个能帮我一下 我有一个数据库,大约有10k个条目。 我使用-class中的默认查询方法查询元素。 查询本身足够快 一旦查询完成,我必须在谷歌地图上显示结果。 为此,我从保存标记信息的游标生成一个结果数组 我使用的方法有点像这样: final ArrayList< MarkerElement > result = new ArrayList< MarkerElement >(); cursor.moveT

我正在处理我的一个应用程序中的性能问题。也许你们中的一个能帮我一下

我有一个数据库,大约有10k个条目。 我使用-class中的默认查询方法查询元素。 查询本身足够快

一旦查询完成,我必须在谷歌地图上显示结果。 为此,我从保存标记信息的游标生成一个结果数组

我使用的方法有点像这样:

    final ArrayList< MarkerElement > result = new ArrayList< MarkerElement >();
    cursor.moveToFirst();
    while ( !cursor.isAfterLast() ) {
        result.add( new MarkerElement(
                cursor.getString( COL_TITLE ),
                cursor.getString( COL_SNIPPET ),
                new LatLng(
                        cursor.getDouble( COL_LAT ),
                        cursor.getDouble( COL_LNG ) ),
                cursor.getString( COL_OTHER_USEFUL_DATA ) );
        cursor.moveToNext();
    }
    cursor.close();
final ArrayListresult=new ArrayList();
cursor.moveToFirst();
而(!cursor.isAfterLast()){
结果。添加(新标记元素)(
cursor.getString(COL_TITLE),
cursor.getString(COL_代码段),
新车床(
cursor.getDouble(COL_LAT),
cursor.getDouble(COL_LNG)),
getString(COL_其他有用的数据);
cursor.moveToNext();
}
cursor.close();
其中MarkerElement只是一个类,它保存Google地图上标记所需的值

现在的问题是,在所有游标元素之间循环要花很长时间。 此外,我想不出像ListView那样延迟加载结果的聪明方法,因为我需要同时显示所有结果

我能做些什么来显著加快这个过程

非常感谢您的帮助


致以最诚挚的问候

我不确定查询是否真的像您想象的那样快。最有可能的是,实际查询只使用cursor.moveToFirst()语句执行,而不是在调用query()或rawQuery()时执行(或您正在使用的任何其他查询方法)

无论如何,查询应该足够快,以使用户只需等待很短时间。如果没有,那么您可能需要考虑使用来自Youl表限制开始的SELECT*来将其加载到块中(计数,例如从Youl表限制0, 1000中选择*以检索前1000行)。 查询无法在ui线程上发生,因此您希望在AsyncTaskLoader或更好的游标加载程序中运行它。可以使用不带ContentProvider的游标加载程序,如下所示:

假设您需要为每个1000条记录运行10个查询,那么您将有10个游标加载程序,可以使用LoaderManager进行管理。LoaderManager管理游标(打开和关闭它们),保留跨方向更改的游标,并在后台任务中运行所有内容,因此不会出现阻止ui线程的问题。LoaderManager还会在内容更改时重新查询数据库(请参阅:)。 当LoaderManager通知片段或活动游标已完成加载时,它将调用onLoadFinished()(请参阅:)

减慢代码速度的不仅仅是查询数据库,还包括创建10000个MarkerElement和另外10000个LatLng对象。我不知道您的要求,但如果您发现没有这些对象也可以工作,那么肯定会加快代码速度。消除MarkerElements/LatLng的另一个理想效果是内存使用。For一个应用程序针对手机2万个对象,有3个字符串和2个双字符串,这是相当可观的

使用CursorLoader和LoaderManager将允许您从光标检索值,并直接填充ui视图,而无需标记元素和LatLng。它还允许您延迟加载。只要为其中一个CursorLoader(onLoadFinished()调用onLoadFinished(),您就可以填充视图在ui线程上调用,除非从非ui线程调用initLoader/restartLoader)。如果一次填充1000个视图太多,请将查询分解为更小的部分,或者添加一种机制,以10或100个块(对于每个游标)填充视图

如果您需要当前存储在MarkerElement中的信息,例如,当用户选择其中一个标记时,请在显示标记的视图上使用setTag()来存储db记录的主键。使用该键可以从db中检索记录,或者更好地从已查询的游标中检索记录(这需要一些映射机制,但它是可行的)

总结:

  • 将查询拆分为多个子查询以检索较小的数据集
  • 使用游标装入器和游标管理器管理不同的查询/游标
  • 不要为每一行创建MarkeElement和LatLng,而是直接从返回的游标填充视图
  • 可能需要分几个步骤来填充每个光标,以保持ui的响应性
  • 在视图上使用setTag()可以检索视图后面的数据