我有一个Android应用程序,它使用AlarmManager来安排事件。当收到来自AlarmManager的Intent时,域逻辑必须做一些工作,包括访问数据库和广播意图。目前我使用Singleton以一种方式从BroadcastReceiver(在清单中注册)访问域逻辑:
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Singleton.getInstance().onAlarmFired();
}
}
此Singleton以相同的方式用于活动和服务。 它运行正常,但Singleton被认为是反模式,我想用测试来覆盖代码,所以我正在寻找一个不同的解决方案。
现在的问题是,使用服务代替这个Singleton不是更好吗?像这样:
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
startService(new Intent(intent.getAction());
}
}
有什么好处和缺点?什么是与Activity通信的最佳方式?我正在考虑绑定到MyApplication中的服务,并使用getApplication()方法提供对活动和服务的引用。
答案 0 :(得分:2)
现在的问题是,使用服务代替这个Singleton不是更好吗?
是的,非常如此。关于BroadcastReceiver.onReceive()
的主要指令是尽可能少地在metod内部进行响应,因为执行是在主线程上完成的,如果BroadcastReceiver
活着超过10秒,它会很快成为死亡候选人(see the docs for more)。
调用Service
来完成工作是一个完美的替代实现,并且很快从onReceive()
返回。
根据您Service
正在做的事情,您可以将其绑定到Activity
以在其上调用方法,或者只是继续使用Intents
来回发送数据(您可能会想要查看支持库中LocalBroadcastManager
的后一种情况。)
我正在考虑在MyApplication中绑定服务,并使用getApplication()方法提供对活动和服务的引用
我强烈反对这一点。在许多情况下,我会考虑使用Application
类也是一种反模式。与生成的Singleton相比,它的生命周期并不容易。相反,如果要绑定Service
以便使用它,请将其绑定到当前位于前台时想要访问的任何Activity
。
编辑:关于系统服务的问题
系统服务和应用服务非常不同;系统服务根本不是服务(在单词的SDK定义中)。它们是在system_server
进程内运行的Singleton对象,它们可以防止中断,并与您可以使用AIDL和IPC访问的管理器对象进行通信。
您的应用程序中的单身人士不具备相同的奢侈品。如果您的应用程序崩溃,Android无法帮助重新启动您的obhect。但更重要的是,由于它不是注册的系统组件,如果您在后台执行代码,Android将无法将您的应用程序识别为执行有效的后台工作,如果您的应用程序不是,则您将更有可能成为低内存查杀的目标在前台。
因此,虽然技术上使用Singleton会有效,但将代码转换为传统的Service
被认为是最佳做法,并且会从平台本身中获得最大的好处。