2011-12-16 42 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