2011-12-16 43 views
2

我有一个安装程序,我在Android中运行后台服务,附带一个BroadcastReceiver监听特定类型的Intents。这些意图然后由广播接收机用于调用服务中的特定方法。以下是描述服务结构的代码:从应用程序类广播意图到Android服务的麻烦

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)); 

..它只适用于如果我从一个活动内部调用它。但是,即使在应用程序首次启动时,我也希望能够“执行某些操作”,因此在创建MyService并启动它之后,我已将该语句放入onCreate()方法的自定义Application子类中。出于某种原因,当应用程序启动时,广播不能在Application类代码中工作,但是如果我将它放在某个活动内的某个代码中(例如在活动的onCreate()方法中),它就会工作。我可以确认服务的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)); 

     } 

} 

注意,我开始服务其实我做之前,广播。该服务不接收广播,但如果我从稍后启动的活动执行类似的呼叫,它确实收到。

回答

6

您的Application在流程中的任何其他组件之前创建。因此在onCreate()中没有Serivce正在运行。如果您在调用应用程序的onCreate()时发送广播,Service没有注册广播接收器,因为它甚至没有创建。

因此,换句话说,您的服务没有收到广播通知,因为广播接收器尚未注册。而且它尚未注册,因为Service尚未启动。并且在设计返回应用程序的onCreate()之前它不能启动。

您可以使用应用程序的onCreate()中的Context.startService()直接启动服务。您将能够通过Intent找到所有必需的数据。


更新答案更新的问题:

当你拨打:

getApplicationContext().startService(intent); 

你问的Android在一段时间后启动服务。服务不是马上开始。它只是计划在稍后开始。实际上,在您从应用程序的onCreate()函数返回之前,它绝对不会启动。这是因为所有Service的生命周期回调函数(如onCreate()onStart())都是从主UI线程调用的。并且应用程序的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); 
+0

见我的更新上面,我会尽力实际广播之前启动该服务。 – Faisal 2011-12-16 19:27:23