0

我有一个 Android 应用程序,它使用 AlarmManager 来安排事件。当收到来自 AlarmManager 的 Intent 时,域逻辑必须做一些工作,包括访问数据库和广播意图。目前我使用单例从广播接收器(在清单中注册)以某种方式访问​​域逻辑:

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Singleton.getInstance().onAlarmFired();
    }
}

这个 Singleton 以相同的方式用于活动和服务中。它工作得很好,但是 Singleton 被认为是一种反模式,我想用测试来覆盖代码,所以我正在寻找一个不同的解决方案。

现在的问题是使用 Service 而不是这个 Singleton 不是更好吗?像这样:

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        startService(new Intent(intent.getAction());
    }
}

有什么好处和坏处?从 Activity 与服务进行通信的最佳方式是什么?我正在考虑绑定到 MyApplication 中的服务,并使用 getApplication() 方法提供对活动和服务的引用。

4

1 回答 1

2

现在的问题是使用 Service 而不是这个 Singleton 不是更好吗?

是的,非常如此。涉及到的主要指令BroadcastReceiver.onReceive()是响应在方法中花费尽可能少的时间,因为该执行是在主线程上完成的,如果BroadcastReceiver它存活超过 10 秒,它很快就会成为死亡的候选者(参见文档更多)。

相反,调用 aService来完成工作是一个完美的替代实现,并且可以onReceive()很快返回。

根据您Service的操作,您可以将其绑定Activity到调用方法,或者只是继续使用Intents来来回发送数据(您可能需要查看LocalBroadcastManager支持库中的后一种情况)。

我正在考虑绑定到 MyApplication 中的服务并使用 getApplication() 方法提供对活动和服务的引用

我强烈反对这一点。在许多情况下,我会考虑使用Application该类也是一种反模式。关注它的生命周期并不比创建的 Singleton 更容易。相反,如果要绑定Service以使用它,请将其绑定到Activity当前处于前台时想要访问的任何对象。

编辑:关于系统服务的问题

系统服务和应用服务有很大不同;系统服务甚至根本不是服务(在 SDK 对这个词的定义中)。它们是在system_server进程内部运行的单例对象,它们在其中受到保护,不会被中断,并与您可以使用 AIDL 和 IPC 访问的管理器对象对话。

您的应用程序中的 Singleton 没有同样的奢侈。如果您的应用程序崩溃,Android 将无法帮助您重新启动对象。但更重要的是,由于它不是已注册的系统组件,如果您在后台执行代码,Android 将不会识别您的应用程序正在执行有效的后台工作,如果您的应用程序不是,您将更有可能成为低内存杀死的目标在前台。

因此,虽然在技术上使用 Singleton 是可行的,但将您的代码移动到传统的代码Service中被认为是最佳实践,并且将使您从平台本身中获得最大的收益。

于 2012-07-25T22:38:47.170 回答