从Android中的BroadcastReceiver访问应用程序域逻辑的首选方法是什么?

时间:2012-07-25 22:27:41

标签: android singleton

我有一个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()方法提供对活动和服务的引用。

1 个答案:

答案 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被认为是最佳做法,并且会从平台本身中获得最大的好处。