8

我想知道创建一个在某些 Android 活动和 Android 服务之间使用的单例是否是个坏主意。据我所知,只要整个流程还活着,就可以使用静态字段,在我的例子中是单例。

我的计划是使用单例而不是 Parcelable 在我的活动和后台服务之间共享数据。所以我的 Activity1 将通过调用 MySingleton.getInstance().addData(foo); 添加一些数据;然后我会发送一个 Intent 通知我的服务新数据已添加到单例中。接下来,我的 BackgroundService 将处理意图并调用 MySingleton.getInstance().getLatestData(); 然后它将处理数据(需要一些时间)。服务的结果接下来将通过使用单例“发布”回来并触发广播意图,这些意图由 Activity1(如果还活着)处理,并且 Activity1 将从单例中检索结果。

你们认为这是一个坏主意吗?

编辑:我想要实现的是从 Web 服务器下载数据并解析它并返回结果的软件的和平。所以我的 Activity 会创建 DownloadJob 对象。DownloadJob-Object 将被放入排队和管理所有 DownloadJobs 的 DownloadScheduler (Singleton)。DownloadScheduler 将允许同时运行 5 个 DownloadJobs 并使用队列来存储等待。有效的下载将由 DownloadService (IntentService) 完成,它通过 Intent 获得通知,现在应该立即执行(下载)新的 DownloadJob。DowanlodService 将从 DownloadSchedulers 队列 (PriorityBlockingQueue) 中检索下一个作业,并通过设置 DownloadJob.setResult(...) 返回 Result 并启动广播意图,即 Result 已准备好,

因此,在我的场景中,我将使用单例从 DownloadService 访问 DownloadJobs,而不是制作 DownloadJob Parcelable 并将其与 Intent 一起传递。所以我会避免这个问题,我在内存中有两个 DownloadJobs(一个在“活动站点”上,一个在“服务站点”上)。

有什么建议可以更好地解决这个问题吗?

像 DownloadScheduler(Singleton) 这样的静态实例是否会被 android 系统在低内存上释放?那么将应用程序子类化并保留引用(非静态)会避免这个问题吗?

4

3 回答 3

3

如果您将单例用作后台服务之间的共享内存,我假设它在不同的线程上执行操作,您可能会遇到同步问题或读取不一致的数据。

如果单例中的数据不同步,则必须小心,因为您依赖“协议”来确保在后台线程正在写入时没有人在读取(这可能会导致错误)。

另一方面,如果它是同步的,您将面临面临错误的风险,因为读取数据的活动可能会被阻塞,等待服务完成将数据写入单例中。

正如另一位所说,您还必须记住,如果操作系统需要资源,您的单例可能会被释放,并且您的数据可能不再存在。

我宁愿使用ottoeventbus 之类的事件总线

编辑:

使用单例作为后台(意图)服务的入口点是 2010 年 Virgil Dobjanschi谈论为 android 构建 rest 客户端应用程序所建议的方法。

建议的方法是使用一个单例来作为正在进行的请求的控制器。还请考虑对意图服务的请求已经由操作系统排队,因此您可以抛出几个意图,这些意图将由意图服务按顺序处理。

前段时间我还尝试以此为起点创建一个图书馆,但仍未完成。你可以在这里找到来源

我当然不会做的是将您的数据存储在单例中。我更喜欢的方法是将数据存储在一些持久性存储中(例如 sql/preferences/file/content provider),并通过广播消息让客户端知道更改(或者,如果您使用的是 content provider,则通过观察者)。

最后,在某种程度上,这是robospice库遵循的方法,它看起来相当成熟,并提供了许多有趣的功能,例如缓存。

于 2012-11-23T03:47:42.040 回答
1

一个更好的想法是继承 Application 并将任何长期存在的对象放在那里。通过继承 Application 您可以正确处理应用程序的启动和关闭,这是单例无法轻松完成的。此外,通过使用应用程序,活动和服务可以共享对程序中模型的访问,而无需借助 parcelables。而且你可以避免单例给你的程序带来的所有问题。

您也不必求助于将所有内容存储在数据库中,这需要大量样板代码才能将一堆数据推入其中。它对在应用程序的各个部分之间共享行为没有任何作用,也没有对促进活动的通信和集中化做任何事情。如果您真的需要在关闭之间保持状态,请使用它,但如果不需要,您可以为自己节省大量工作。

您还可以考虑使用Roboguice 之类的东西,它可以将共享模型注入到您的活动和服务中。

您可能会发现这很有帮助:

Android开发中的设计模式原则是什么?

于 2012-11-23T03:38:40.060 回答
0

使用这样的单例并不一定是个坏主意,但是如果 Android 决定停止您的进程,您将失去它的状态。您可能需要考虑将状态存储在 SQLite 数据库或持久队列中(以磁带为例)。

于 2012-11-23T03:38:11.907 回答