如何在应用启动时启动Android服务?

15

我对Android仍然很生疏,我认为以下配置适用于在应用程序启动时启动我的服务。

    <service android:name=".PlaylistUpdaterService">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </service>

但事实并非如此。我错过了什么?

2个回答

25

错误! 扩展 Application 类(即创建您自己的类),然后在 onCreate() 方法中执行此操作。

//Service is below
Intent serviceIntent = new Intent(getApplicationContext(), PlaylistUpdaterService.class);
startService(serviceIntent);

把你在清单文件中的声明中的那个意图过滤器垃圾删掉。将其保留为

<service android:name=".PlaylistUpdaterService">

以下意图过滤器仅需在您的主页活动中使用

<intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> 
这样做的原因是因为 Application 类在应用启动时立即启动,并充当 Android 框架管理的全局类。
实际上,如果您想让服务在每次返回主屏幕时都运行,您应该在主屏幕类的 onResume() 中启动服务。将它放在应用程序的 onCreate() 中仅会在用户首次启动或运行进程被杀死后才启动服务。或者,您可以将其放在主屏幕类的onCreate()中,但这甚至不能保证每次都会运行。

如果您希望服务仅在启动时启动,则这不是适当的方法。每次用户更改方向时,服务都会启动。我也正在寻找解决方案。 - DerpyNerd
4
如果一个服务正在运行,再次调用“start”将不会有任何作用。这是默认行为。 - Aaron T Harris
2
@AaronTHarris,您在某种程度上是正确的,但在这种情况下并不适用,因为在方向更改事件(即屏幕旋转)中不适用于Android的应用程序类。 Application.onCreate()仅在应用程序启动时调用一次,并在应用程序被杀死并重新启动时再次调用。 - Danuofr
@Danuofr 我没有错。我在谈论同时存在的实例,就像我在 onResume 中说的“多次”,并且如我在原帖中所说,“如果服务正在运行,第二次调用启动将什么也不会做”。我指出Android不允许在一个实例已经在运行时启动相同的服务。 - Aaron T Harris
1
@AaronTHarris 我想你可能已经注意到了,因为这是去年的讨论,但只是为了确保。看起来你没有理解Danuofr的观点。你的陈述部分正确,但他的实现方式并不是那样的。请注意Danuofr评论中的关键字“Application”。他从未与任何Activity一起工作,因此方向更改首先不会影响他的实现。Application没有onResume,但Activity有。他答案的最后一段是关于一些罕见的异常情况。 - Curious Sam
显示剩余6条评论

9
请纠正我,如果我错了的话,android.intent.category.LAUNCHER只适用于Activity。因此,看起来不是启动Service的有效方式。如果您执行以下操作,则可以实现相同的效果:
创建透明Activity仅用于启动Service;
对于该Activity,您无需指定GUI布局。因此,在activity的onCreate()中,您不需要调用setContentView()。您唯一需要做的就是在AndroidManifest.xml中为此Activity放置@android:style/Theme.NoDisplay标签;
从Activity的onCreate()中启动Service;
在Activity的onStart()中调用finish()以关闭它。
这样,您的Activity将对用户不可见,持续时间短暂,没有人会注意到它被用于启动服务。

1
这种方法会在活动运行时锁定UI,但由于它被设置为半透明,所以无法进行任何操作。有没有办法避免UI锁定? - Akhil Latta
@Noble6 - 已更新我的答案,使其更加清晰。感谢您宝贵的评论。 - Zelimir
4
不需要使用活动,这只会因为启动和停止活动的开销而降低应用程序的感知启动时间。覆盖应用程序的下面方法更好。但是,如果你真的想从活动开始,最好有一个基本活动,如果服务还没有启动,则将服务作为默认行为启动,然后让所有活动都扩展该基本活动。 - Aaron T Harris
真的。完全同意。很久以前就放弃了这种幼稚的方法。 - Zelimir

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