1

我有一個應用程序具有單個活動,該活動在一種自定義導航抽屜設計中承載多個片段。這些片段中的兩個依賴於服務來返回它們的json信息來顯示。 我希望能夠在我的啓動畫面上啓動服務以加載我需要的數據,然後將json異步通信到這些片段。Android服務與多個片段進行通信

我是新來的android和編程的一般,所以如果我的行動是不明智的消息,但我第一次嘗試註冊片段作爲接收器,然後簡單地廣播包含json信息捆綁意圖。這似乎不起作用,因爲有時候服務會播出意圖而錯過意圖時,碎片不會運行。

然後我決定用粘性的意圖去,但這導致陳舊的信息,更不用說繼承安全問題了。

什麼是讓服務在啓動應用程序時執行後臺網絡請求,然後通過任何活動或片段顯示返回的信息的最佳方式?

+0

使用LocalBroadcastManager時,沒有安全隱患。 http://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html – a11n 2014-12-02 15:59:17

回答

1

你可以調用startService(),不僅從您的閃屏,但是從你的片段:getActivity().startService()

Service(不是IntentService)派生您的服務。在onStartCommand()它將從網絡讀取數據,然後廣播結果。如果結果已經加載,服務可以簡單地廣播結果。

當您從閃屏呼叫startService()時,服務會從網絡加載數據並將其廣播到當前顯示的片段。當創建新的片段時,它會再次調用startService()並且服務廣播緩存的數據。

另一種方法是bindService。您的片段可以綁定到onCreate()上的服務,並在onDestroy()上解除綁定。在這種情況下,片段可以直接調用服務的方法。

+0

謝謝,我認爲你的解釋正是我所尋找的 – feilong 2014-12-02 19:28:11

3

相信我,我在大型企業項目中嘗試了很多第三方方法(服務總線,觀察...),結果證明原生Android機制是最快和最健壯的方法,因爲他們利用框架的好處。

這就是爲什麼我會建議使用LocalBroadcastManager與BroadcastReceiver一起使用。在你的活動(或你的罐頭事件做這個每個片段!)註冊在onStart和取消註冊在專用的接收器。

在您的服務中使用LocalBroadcastManager與所有潛在訂戶進行通信。

例子:

public class YourActivity extends Activity{ 

     private BroadcastReceiver receiver = new BroadcastReceiver(){ 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      //...do the stuff you need to do depending on the received broadcas 

     } 

}; 

    private IntentFilter filter = new IntentFilter(UploadService.INTENT_ACTION_UPLOAD); 

    protected onStart(){ 
     LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter); 
    } 

    protected onPause(){ 
     LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver); 
    } 
} 

public class UploadService extends IntentService{ 
    public static final String INTENT_ACTION_UPLOAD = "com.your.package.INTENT_ACTION_UPLOAD"; 

    public onHandleIntent(){ 
     //upload 
     LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(INTENT_ACTION_UPLOAD)); 
    } 
} 

在廣播接收器的onReceive那麼你可以做你需要根據接收到的廣播做的東西。如果您需要更多的差異化,你可以在你的服務使用不同的動作或演員,比如:

...send(new Intent(INTENT_ACTION_SOMETHING_ELSE)); 

send(new Intent(...).putExtra(WAS_SUCCESSFUL, false)); 
send(new Intent(...).putExtra(DOWNLOADED_CONTENT, downloadedStuff);