创建仅一个服务实例(Android)

34

如何确保只创建一个Service实例?

我已经使用日志记录了一些函数(WeatherService是扩展Service的类):

Log.i(TAG, "Start  Id:" + WeatherService.this.hashCode());
Log.i(TAG, "End Id:" + WeatherService.this.hashCode());

即使我确定相同的函数运行两次(下载),它也会给出不同的哈希码:

09-12 01:00:55.195: INFO/WeatherService(7222): Start  Id:1137653208
09-12 01:00:57.235: INFO/WeatherService(7222): Start  Id:1137654296
09-12 01:00:59.035: INFO/WeatherService(7222): Start  Id:1138806536
09-12 01:01:39.085: INFO/WeatherService(7222): End Id:1137654296
09-12 01:01:39.265: INFO/WeatherService(7222): Start  Id:1137654296
09-12 01:02:22.175: INFO/WeatherService(7222): End Id:1137653208
09-12 01:02:24.815: INFO/WeatherService(7222): End Id:1138806536
09-12 01:02:24.836: INFO/WeatherService(7222): Start  Id:1138806536
09-12 01:02:40.275: INFO/WeatherService(7222): End Id:1137654296

我正在使用以下代码将Activity与服务绑定:

bindService(new Intent(getApplicationContext(),  WeatherService.class)
                               ,mServiceConnection, BIND_AUTO_CREATE);

服务可以运行数分钟直至完成,因此该服务可以绑定/由多个Activity创建。


还可以查看这个页面,我觉得它也有一个有用的解释:https://dev59.com/qHE85IYBdhLWcg3w_Itr - user1499731
2个回答

32

如何确保只创建一个 Service 实例?

给定的 Service 只能有一个实例。

即使我确定同一个函数运行了两次(下载),它也会返回不同的哈希码。

那么这个 this 不是指代该 Service。或者,在记录日志之间,服务已被销毁并重新创建。

该服务可能会运行数分钟,直到完成,因此服务可以被多个 Activities 绑定/创建。

那么该 Service 可能正在被销毁和重新创建。如果您需要服务运行数分钟,则需要在使用 bindService()unbindService() 调用之外,使用 startService()stopSelf()。或者,如果您不需要绑定服务,则可以考虑使用 IntentService,因为它会自动为您提供一个后台线程来执行下载操作。


哦,这意味着只有一个服务会被启动?如果再次调用它,onCreate 不会被调用,只有 onstart。 - Sunil Pandey
10
顺便问一下,你有支持“给定服务只能有一个实例”的任何来源吗? - Pacerier
6
我不同意这个答案。我曾经遇到过多个具有不同哈希码的服务同时存在且都是活动和正常运行的情况。通常情况下,当一个服务被解除绑定然后重新绑定时,原来的服务似乎在一段时间内仍然存在。我一直无法找出如何处理这种情况的不同方法。 - Peter Gaultney
@PeterGaultney:“我曾经遇到过多个具有不同哈希码的服务同时存在的情况,而且它们都是活跃和运行的”--欢迎您发布一个演示此行为的示例项目。 - CommonsWare
@GlennMaynard:“在同一个进程中构建了两个实例,然后在每个实例上调用onStartCommand”--也许其中一个被销毁了,但你泄漏了一个线程,并且该线程仍在继续运行。正如我7年前所写的那样,欢迎您发布一个演示您所声称的行为的示例项目。 - CommonsWare
显示剩余3条评论

14

我曾经遇到类似的情况。
如果你已经按照以下方式编写,可以创建一个以上的实例。

bindService(new Intent(getApplicationContext(),  WeatherService.class), mServiceConnection, BIND_AUTO_CREATE);

尝试按以下方式编写。
getApplicationContext().bindService(new Intent(getApplicationContext(), WeatherService.class),mServiceConnection, BIND_AUTO_CREATE);

1
这正是我所缺少的,因为似乎你可以多次启动一个服务(我有一个服务每五秒钟应该显示一次toast,但在使用此技巧之前,它会每秒钟显示2、3甚至更多次toast,每次我使用bindService)。谢谢! - liltof

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接