从广播接收器启动服务

79

我在我的应用中有一个ServiceBroadcastReceiver,但是如何直接从BroadcastReceiver启动服务?使用

startService(new Intent(this, MyService.class));

在广播接收器(BroadcastReceiver)中无法工作,有什么想法?

编辑:

context.startService(..);

可以工作了,我忘记了上下文部分。

7个回答

116

Don't forget

context.startService(..);


2
完美的答案。只需要稍微读一下就把它修复好了。 - grepsedawk
1
同时请查看此链接 https://groups.google.com/forum/#!topic/android-developers/WVoO8kQCFF0 context.startService(new Intent(MusicService.ACTION_PAUSE, null, context, MusicService.class)); - cwhsu
2
这非常有帮助。 - midiwriter
非常感谢你的帮助... :) - G droid
“Context” 应该是什么? - Virus721
它崩溃了:android.app.RemoteServiceException:Context.startForegroundService()没有调用Service.startForeground()。 - Bhaven Shah

61

应该是这样的:

Intent i = new Intent(context, YourServiceName.class);
context.startService(i);

请务必将该服务添加到manifest.xml文件中


典型的清单项(放在<application>下,与<activity>处于同一“级别”): <receiver android:name=".YourServiceName"></receiver> - Art Swri
@ArtSwri 应该是 <service android:name=".YourServiceName"></service> 而不是 receiver。 - Rahul

14

使用您的BroadcastReceiveronReceive方法中的context,以启动您的服务组件。

@Override
public void onReceive(Context context, Intent intent) {
      Intent serviceIntent = new Intent(context, YourService.class);
      context.startService(serviceIntent);
}

终于有人关心提到“上下文”是什么了。谢谢。 - Virus721

7

最佳实践:

在创建意图时,特别是从 BroadcastReceiver 开始时,不要将 this 作为上下文。
请使用以下方式获取 context.getApplicationContext()

 Intent intent = new Intent(context.getApplicationContext(), classNAME);
context.getApplicationContext().startService(intent);

1
是的,我们应该传递context.getApplicationContext(),否则应用程序会崩溃。 - Vijay
1
请说明原因? - Virus721
2
为什么会这样:与上下文相关的接收器只要其注册上下文有效,就可以接收广播。例如,如果您在 Activity 上下文中注册,则只要该 Activity 未被销毁,就可以接收广播。如果您使用应用程序上下文进行注册,则只要应用程序正在运行,就可以接收广播。 - ARUN
仍然对我崩溃。 - zezba9000

4
 try {
        Intent intentService = new Intent(context, MyNewIntentService.class);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(intentService );
        } else {
            context.startService(intentService );
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

2

最好使用ContextCompat:

Intent serviceIntent = new Intent(context, ForegroundService.class);
ContextCompat.startForegroundService(context, serviceIntent);

0
因为接收器的onReceive(Context, Intent)方法在主线程上运行,所以它应该快速执行并返回。如果您需要执行长时间运行的工作,请小心生成线程或启动后台服务,因为系统可能会在onReceive()返回后杀死整个进程。有关更多信息,请参见进程状态的影响。为了执行长时间运行的工作,我们建议:
在接收器的onReceive()方法中调用goAsync()并将BroadcastReceiver.PendingResult传递给后台线程。这使广播在从onReceive()返回后保持活动状态。但是,即使使用此方法,系统也希望您非常快地完成广播(不到10秒)。它确实允许您将工作移动到另一个线程以避免干扰主线程。 使用JobScheduler安排作业 developer.android.com

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