Android:扩展用户的联系簿。性能ContentProvider vs Sqlite vs内存中的List

时间:2013-01-27 09:29:35

标签: android performance sqlite android-contentprovider android-cursoradapter

我和我的Android团队有问题。我们有一个应用程序,可以显示用户的联系簿,并提供扩展信息。

当前设置

我们的应用程序会读取Android操作系统的联系人提供程序。将此信息发送到我们的服务器,为我们计算几个必要的字段。稍后我们的应用程序会提取此信息,并将此信息保存在SQLite数据库中。我们在数据库中最终得到的是两个表格。一个包含所有数字和服务器为我们计算的所有额外信息。另一个表是所有联系人(一个联系人可以有多个号码)。此联系人表仅为性能而创建;我们可以让Cursor在为用户呈现联系簿时选择CursorAdapter中此Contacts表中的所有行。 因此,当向用户呈现联系簿时,我们只需要从我们自己的SQLite数据库中读取并且只需要读取一个表(例如,没有JOIN)。

主要问题

有很多同步正在进行中。由于数据是重复的,我们需要检查添加/更改/删除,并需要同步所有的fing时间。此外,当我们现在要更改表示层中的特定内容时,我们需要更改“联系人”表以包含此特定信息。

我们的优先级

1st:向用户出示联系簿时的表现。

第二:代码可维护性。

因此,不要评论“不要重复数据 - 它是所有问题的根源”。对我们来说,更重要的是用户没有性能问题,因为开发人员不得不花费额外的时间来编写良好的同步算法。

方案吗

我不知道为什么,但我一直认为CursorAdapter(读取一个表中的所有行)的性能远远超过带有List对象(保存在内存中)的ArrayAdapter。谁知道这是真的吗?因为一个能够帮助我们至少一半的解决方案是在启动时加入Contacts Provider(本地联系簿)和我们的扩展信息,将其保存在内存列表中并使用ArrayAdapter呈现。

创建自己的内容提供商?我对创建自己的内容提供商知之甚少。任何人都试图创建一个内容提供者来扩展本地联系簿的信息并加入这些内容。也许与这个接口的实现:ContactsContract.DataColumnsWithJoins?有人试过类似的东西?在CursorAdapter中显示此信息时的性能如何?

请询问我可能忘记的更多信息,我会更新问题!

提前感谢所有有用的提示和解决方案!

2 个答案:

答案 0 :(得分:1)

我得出结论(在我的应用程序JReader上依赖于快速数据库操作),Android中的SQLite与其他平台一样快,但有一些Android特定问题。 一些关于数据库性能和您提出的问题的建议:

  • 如果您不打算通过它们共享数据,内容提供商几乎没用。但它们提供至少2个优点。首先你获得数据更改通知,你的光标会自动更新,第二个也是重要的一个:CursorLoaders需要一个内容提供者,如果性能对你很重要,我强烈建议用它们加载光标;
  • 访问集合访问数据库的速度要快得多,但这是一项双重工作,因为无论如何都必须保留数据,即使是为超快滚动列表提取数据,特别是单个数据库,数据库访问速度也非常快表,这应该不是问题;
  • 正确设计你的数据库(使用JOINS,索引等):)但是不要在CURSOR查询中使用加入查询!我在多个Android平台(包括4.0+)上遇到了很多性能问题,但并非总是如此。我访问联合表的方法是先获取外键,然后查询子表。

根据我的经验,我遇到过数据库性能非常差的情况,但最终我总是设法调整代码,因此性能提升10-100倍。因此,不断分析数据库代码,您肯定会达到预期的性能。

答案 1 :(得分:0)

Dan的第二条评论是真的.. Android使用屏幕下方的Cursor Window来缓存Cursor中的数据(大约1M)。请参阅Android docs on Cursor Window,游标适配器的速度更快。

如果你不喜欢单独连接两个表,你可以考虑更快的CursorJoiner,这可以转到你的自定义contentProvider,其中一个提供者指向Contacts并返回一个Cursor,类似的第二个指向你的拥有表并返回一个游标。 cursorjoiner可以连接这两个游标。

(虽然这是一个复杂的过程)