【问题标题】:Appropriate off-thread database interface for small apps in Android适用于Android中小型应用程序的离线数据库接口
【发布时间】:2014-08-09 12:18:46
【问题描述】:

我知道这里有很多与此主题相关的主题,但我还没有阅读我的问题的真正答案,其中很多是从 2010 年开始的,当时似乎没有那么强调让任务脱离 UI 线程。

我需要进行一个足够密集的数据库查询,它会导致 UI 响应明显延迟(在我的 S5 上,所以在很多手机上会更糟)。我想将查询推送到另一个线程。我一直在使用 ASyncTask 这样做,但我了解到 ASyncTask 存在问题,以及屏幕旋转、中断应用程序和内存泄漏等问题。我到处看到的建议是使用 CursorLoader,但其构造函数需要 Uri,因为它是为内容提供者设计的。不仅内容提供者对我的应用程序来说似乎有点矫枉过正,而且谷歌的内容提供者教程页面特别指出“如果完全在你自己的应用程序中使用 SQLite 数据库,你不需要提供者来使用 SQLite 数据库。”

所以我的问题是,如果有的话,ASyncTask 和内容提供者之间存在什么?是否有用于内部数据库的 CursorLoader 实现?也许是 ASyncTask 的更强大的实现?

【问题讨论】:

  • 您可能希望创建一个服务并使用队列驱动该服务(这样可以减少连接到数据库的设置量)。

标签: java android multithreading sqlite android-asynctask


【解决方案1】:

我一直在使用 ASyncTask,但我了解到 ASyncTask 存在问题,例如屏幕旋转、中断应用程序和内存泄漏。

AsyncTask 正确使用有点棘手。拥有一个 managed by a retained fragment(例如,模型片段)会有所帮助。

是否有任何用于内部数据库的 CursorLoader 实现?

没有一个效果很好。我说这已经写了(并且已经被弃用了)一个。 The Loader interface is an abstraction designed around a singular use case: ContentProvider

也许是 ASyncTask 的更强大的实现?

并不是AsyncTask 需要“更强大”,而是您必须意识到它存在的各种问题。例如,自吹自擂的CursorLoader 使用AsyncTask

归根结底,AsyncTask 所做的只是使用线程池中的后台线程,并将通信返回给主应用程序线程以获取工作结果。有许多方法可以达到同样的目的。目前,我喜欢结合an ordinary thread 使用greenrobot's EventBus(或者线程池中的一个,如果可能有很多同时发生的事件)。除此之外,您还可以:

  • 使用带有Handler 的普通线程
  • View 上使用带有post() 的普通线程
  • Activity 上使用带有runOnUiThread() 的普通线程

所有这些都假定作品相当短且可随意使用,就像您的情况一样。对于较长和/或较少一次性的工作,请使用IntentService,如果工作可能需要几十秒或更长时间,则可能使用my WakefulIntentService

但是,所有这些仍然存在问题,在某些情况下与AsyncTask 本身存在的问题相同(例如,正确解决配置更改)。没有“银弹”。

【讨论】:

  • 谢谢。就在我发布这个之后,我发现了一篇关于在保留片段中使用 AsyncTask 的文章,我认为这会很好。我曾研究过总线实现,但对于一个数据库查询来说,它似乎过于复杂。
猜你喜欢
  • 1970-01-01
  • 2012-10-01
  • 1970-01-01
  • 2015-04-05
  • 2014-01-25
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
  • 1970-01-01
相关资源
最近更新 更多