我知道这里有很多关于这个话题的主题,但我没有看到我的问题的真实答案,其中很多都是从2010年开始,当时似乎没有那么重视保持任务脱离UI线程。
我需要进行一个足够密集的数据库查询,它会导致UI响应明显延迟(在我的S5上,所以在很多手机上会更糟)。我想将查询推送到另一个线程。我一直在使用ASyncTask这样做,但我读到ASyncTask存在问题以及屏幕旋转,中断应用程序和内存泄漏等问题。我到处看到的建议是使用CursorLoader,但是它的构造函数需要一个Uri,因为它是为内容提供者设计的。内容提供商不仅对我的应用程序来说有点过分,而且Google的内容提供商教程页面明确指出“如果使用完全在您自己的应用程序中,则不需要提供程序来使用SQLite数据库”。
所以我的问题是,ASyncTask和内容提供商之间有什么关系?内部数据库是否有CursorLoader的实现?也许更强大的ASyncTask实现?
答案 0 :(得分: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
都使用来自线程池的后台线程,并将通信中介回主应用程序线程以获取工作结果。有许多方法可以实现同样的目的。目前,我喜欢使用greenrobot's EventBus(或者来自线程池的一个,如果可能有很多同时发生的事件),与an ordinary thread一起使用。除此之外,你可以:
Handler
post()
View
的普通主题
runOnUiThread()
Activity
的普通主题
所有这些人都认为这项工作是合理的短期和一次性的,就像你的情况一样。对于较长和/或较少的一次性工作,如果工作可能需要几十秒或更长时间,请使用IntentService
,可能my WakefulIntentService
。
但是,所有这些问题仍然存在问题,在某些情况下会出现与AsyncTask
本身相同的问题(例如,正确解决配置更改)。没有“银弹”。