我想知道创建一个在某些Android活动和Android服务之间使用的Singleton是不是一个坏主意。据我所知,静态字段,在我的情况下,Singleton,只要整个Process处于活动状态就可用。
我的计划是使用单例而不是Parcelable在我的活动和后台服务之间共享数据。所以我的Activity1将通过调用MySingleton.getInstance()添加一些数据.addData(foo);然后我会发送一个Intent来告知我的服务新单元已被添加到单例中。接下来,我的BackgroundService将处理intent并调用MySingleton.getInstance()。getLatestData();然后它会处理数据(需要一些时间)。服务的结果接下来是" post"返回使用单例并触发广播意图,由Activity1处理(如果存活),Activity1将从单例中检索结果。
你们认为这是一个坏主意吗?
编辑: 我想要实现的是一个软件的和平,从Web服务器下载数据解析它并返回结果。所以我的Activity将创建DownloadJob对象。 DownloadJob-Object将被放入DownloadScheduler(Singleton),它将所有DownloadJobs排队和管理。 DownloadScheduler允许同时运行5个DownloadJobs并使用队列来存储等待。有效的下载将由DownloadService(IntentService)完成,它通过Intent通知现在应该执行(下载)新的DownloadJob。 DowanlodService将从DownloadSchedulers队列(PriorityBlockingQueue)中检索下一个作业,并通过设置DownloadJob.setResult(...)返回结果并触发一个广播意图,结果已准备就绪,这将由DownloadScheduler接收,从队列中取出作业并通知活动下载完成等。
因此,在我的场景中,我将使用单例从DownloadService访问DownloadJobs,而不是生成DownloadJob Parcelable并将其传递给Intent。所以我会避免这个问题,我在内存中有两个DownloadJobs(一个在"活动网站"一个在"服务网站")。
如何更好地解决这个问题?
在低内存中由android系统释放的静态实例(例如DownloadScheduler(Singleton))是否正确?那么继承应用程序并保持引用(非静态)避免这个问题吗?
答案 0 :(得分:2)
如果您使用单件只是作为后台服务之间的共享内存,我假设后台服务在不同的线程上执行操作,则可能会遇到同步问题和/或读取不一致的数据。
如果单例中的数据未同步,则必须小心,因为您依赖于“协议”以确保在后台线程正在写入时没有人正在读取(这可能会导致错误)。
另一方面,如果它是同步的,则您可能面临错误,因为可能会阻止读取数据的活动等待服务完成以在单例中写入数据。
正如另一个所说,你还必须记住,如果操作系统需要资源,你的单身人士可能会被释放,而你的数据可能不再存在。
等事件总线编辑:
使用单例作为后台(意图)服务的入口点是2010年Virgil Dobjanschi talk建议的关于为Android构建休息客户端应用程序的方法。
建议的方法是使用单身人员作为持续请求的控制者。请注意,对于意图服务的请求已经由操作系统排队,因此您可以抛出几个意图服务将按顺序处理的意图。
前段时间我还尝试将其作为图书馆的起点,但仍未完成。你可以找到来源here
我当然不会将您的数据存储在单身人士中。我更喜欢的方法是将数据存储在某些持久存储(例如sql / preferences / file / content provider)中,让客户端通过广播消息知道更改(或者,如果您使用的是内容提供商,则通过观察员)。
最后,在某种程度上,这是robospice库遵循的方法,它看起来非常成熟并且提供了许多有趣的功能,例如缓存。
答案 1 :(得分:1)
更好的想法是将Application子类化并将任何长生命对象放在那里。通过子类化Application,您可以正确处理应用程序的启动和关闭,这对于单例来说是不容易的。此外,通过使用应用程序激活和服务,可以共享对程序中模型的访问,而无需使用parcelables。而且你可以避免Singletons为你的程序带来的所有问题。
您也不必将所有内容存储在数据库中,这需要大量的样板代码才能将大量数据存储在那里。它对于在应用程序的各个部分之间共享行为没有任何作用,也没有做任何事情来促进活动的通信和集中化。如果你真的需要在关机之间保持状态,那就很好用,但如果没有,你就可以省去很多工作。
您还可以考虑使用类似Roboguice的内容,这样可以将共享模型注入您的活动和服务。
您可能会觉得这很有用:
答案 2 :(得分:0)
使用像这样的单身并不是一个坏主意,但如果Android决定停止你的过程,你将失去它的状态。您可能需要考虑将状态存储在SQLite数据库或持久队列中(请查看tape以获得一个很好的示例)。