我有一个设置,我在Android中运行后台服务,附加的BroadcastReceiver侦听特定类型的Intents。然后,广播接收器使用这些意图来调用服务中的特定方法。下面是描述服务结构的代码:
public class MyService extends Service {
private class ServiceBroadcastReceiver extends BroadcastReceiver {
private MyService getMyService() {
return MyService.this;
}
public IntentFilter getASReceiverFilter() {
IntentFilter filter = new IntentFilter()
filter.addAction(Constants.ACTION_DO_SOMETHING);
return filter;
}
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
MyService svc = getMyService();
String intentAction = intent.getAction();
Log.i(Constants.LOG_TAG, "Now trying to dispatch following action: " + intentAction);
//Dispatch to the appropriate method in MyService.
if (intentAction.equals(AppServiceConstants.ACTION_DO_SOMETHING)) {
svc.doSomething();
}
}
}
private ServiceBroadcastReceiver mRequestReceiver = new ServiceBroadcastReceiver();
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
Log.i(Constants.LOG_TAG, "Service Created!");
//Register for broadcast messages indicating the add music button was pressed
mRequestReceiver = new ServiceBroadcastReceiver();
registerReceiver(mRequestReceiver, mRequestReceiver.getASReceiverFilter());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(Constants.LOG_TAG, "Service Starting ... ");
// If we get killed, after returning from here, restart
return START_STICKY;
}
/***********************************************************************************
* Service Dispatch Methods
*/
protected void doSomething() {
Log.i(Constants.LOG_TAG, "Doing something");
}
}
我的问题是让这项服务及其广播接收器从我的应用程序中捕获广播意图。如果我做了类似以下的事情......
getApplicationContext().sendBroadcast(new Intent(Constants.ACTION_DO_SOMETHING));
..只有在我从一个Activity中调用它时它才有效。但是,我希望即使在应用程序第一次启动时也可以“做某事”,所以我在创建MyService并启动它之后立即将该语句放在onCreate()方法中我自己的自定义Application子类中。出于某种原因,当应用程序启动时,广播不在Application类代码中工作,但是如果我将它放在活动中的某些代码中(例如在活动的onCreate()方法中),它将起作用。我可以确认在我的Application对象中广播intent之前调用了服务的onCreate()和onStartCommand()方法,但它似乎没有获得意图并执行相关的工作。
任何帮助都将不胜感激。
更新:
以下是我从应用程序发送广播的方式(请注意我先启动服务):
public class MyApplication extends Application {
@Override
public void onCreate() {
Intent intent = new Intent(getApplicationContext(), MyService.class);
getApplicationContext().startService(intent);
getApplicationContext().sendBroadcast(new Intent(Constants.ACTION_DO_SOMETHING));
}
}
请注意,在我实际进行广播之前,我正在启动服务。该服务不接收广播,但如果我从稍后启动的活动中进行类似的呼叫,它确实接收到。
答案 0 :(得分:6)
您的Application
是在流程中的任何其他组件之前创建的。所以在onCreate()
中没有Serivce
正在运行。如果您在调用应用程序的onCreate()
时发送广播,Service
没有注册广播接收者,因为它甚至没有被创建。
因此,换句话说,您的服务未接收广播通知,因为广播接收器尚未注册。它尚未注册,因为Service
尚未开始。并且在应用程序onCreate()
按设计返回之前无法启动它。
您可以使用应用Context.startService()
中的onCreate()
直接启动服务。您将能够通过Intent
路径获取所有必需的数据。
更新了更新问题的答案:
致电时:
getApplicationContext().startService(intent);
您要求Android稍后启动服务。服务不是立即启动。它只安排在稍后开始。事实上,在从应用程序的onCreate()
函数返回之前,它肯定不会启动。这是因为所有Service的生命周期回调函数(如onCreate()
和onStart()
)都是从主UI线程调用的。而Applicaiton的onCreate
目前正在阻止主UI线程。
因此,当您使用以下代码行发送广播时:
getApplicationContext().startService(intent);
getApplicationContext().sendBroadcast(new Intent(Constants.ACTION_DO_SOMETHING));
你实际上要求稍后开始服务,然后立即发送广播。而且因为服务甚至没有机会开始并注册这个广播 通知,它实际上开始时不会收到任何内容。
您可以更改服务的onStart()
代码以处理意图,然后使用以下命令启动服务:
Intent intent = new Intent(getApplicationContext(), MyService.class);
intent.setAction(Constants.ACTION_DO_SOMETHING);
getApplicationContext().startService(intent);