2014-06-19 44 views
11

我正在製作音樂播放器應用程序。我有一個主要的活動,有多個片段,每個顯示設備專輯明智的歌曲,藝術家明智等。
我有一個音樂服務,處理所有的回放和其他的東西。
我很困惑的是這個服務與我擁有的各種片段的綁定。
現在我正在綁定主要活動和每個片段與服務和它的工作非常好。但我想知道這是否是最佳做法?有什麼方法可以將主要活動與服務綁定在一起,然後是一些如何在其子片段中使用它?
我可能會錯過一些非常基本的活動或片段或服務的概念。所以有人請在這方面指導我。
我想這更像是一個概念性問題,所以任何代碼都不需要。但如果需要的話,請讓我知道。將服務綁定到活動或片段?

編輯:
我的問題是:什麼是綁定與多個子片段的活動相關的服務(其中每個將使用該服務)更好的辦法?

+3

綁定它註冊回調取消綁定服務託管你的片段其活性儘快來電forceLoad()。片段採用主機活動的上下文,該活動可以使用getActivity()方法訪問。然後,您可以通過該活動與服務進行交互。試圖綁定到每個片段和活動是一團糟。 – Rarw

+0

@Rarw謝謝你的建議。這是唯一的方式還是有其他選擇嗎? – Anjani

+1

我想這可能會有所幫助:http://stackoverflow.com/questions/15235773/bind-service-to-fragmentactivity-or-fragment – ata

回答

12

綁定Service你的活動,而不是Fragment。你的應用程序的描述,一個活動與多個Fragment交換進出,使這是最實際的方法(也是唯一)。

當您將Service綁定到Activity時,您將其生命週期綁定到Activity的生命週期。 Bound Services。每次在您的活動中添加或刪除Fragment時,Fragment都會被創建並銷燬。您不想嘗試將服務鏈接到此過程,因爲每次創建或銷燬新片段時都必須創建和銷燬該服務。

反而綁定到主機Activity。然後,您可以使用接口訪問綁定服務,或者通過Intent與您的分段中的主機活動交互。

+0

在我現在直到現在的答案中,這個解釋聽起來更合適。所以我現在接受它。謝謝! – Anjani

+0

@Anjani http:// stackoverflow。com/a/15235902/1140321我覺得這個答案更加精確。不要期望每個人都能回答你的問題,並讓它出名。在發佈你的問題之前,還要回顧其他問題。 – Meher

+2

@ 421謝謝指出。在發佈我的問題之前,我實際上已經閱讀了答案。我在發帖前儘可能多地閱讀。但是我仍然不確定同樣的答案是否適用於我的問題,這就是爲什麼我要求這個答案的作者在這裏發表評論,因爲他/她似乎對這個主題有很好的理解。也沒有人發佈這裏獲得知名度,但相互幫助和明確的疑惑。如果通過閱讀一些東西可以清楚地理解我的疑問,爲什麼我會等待幾天才能得到答案。不管怎麼說,還是要謝謝你。我會記住你的建議。 – Anjani

0

您可以通過getActivity()

+0

感謝您的快速回復。我知道這個功能。但是我想問的是,是否建議僅將服務與主要活動綁定,並使用片段中的getActivity()來使用該服務?還是應該將它與單獨的所有活動和碎片綁定在一起? – Anjani

+0

我會綁定儘可能少的實體儘管我不知道如果這是可取的或不。 –

+0

getActivity()可以返回null。更好地使用onAttach(),參考http://stackoverflow.com/a/11743728/763176 – saxman

0

從片段訪問您的活動,你可以使用托盤與此庫事件總線模式,eventbus發佈/訂閱模式。 https://github.com/greenrobot/EventBus檢查項目網站以獲取更多信息。

您可以發送/事件以服務爲主動或片段

+0

雖然我並不需要太多的功能,但我肯定會看看這個庫。謝謝。 – Anjani

0

如果您需要在片段生命週期的開始階段從服務中獲取一些數據到您的片段,則onServiceConnected on活動目前還無法調用,主要是在您旋轉設備時,您將得到一個NPE。 我認爲讓片段創建自己的連接是一個好主意,因爲服務是使用startService()啓動的,而不是使用bindService()。

0

我在我的主機活動中綁定服務,並通過設置在參數中的Bundle傳遞Ibinder的對象。

和我的代碼可能是這樣的:

private ServiceConnection mConnection = new ServiceConnection() { 
    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 
     //put service in bundle 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName name) { 

    } 
}; 
8

我覺得cleanear結構是從片段direcly綁定。關於Rarw答案中概述的問題,您可以將您的活動和碎片中的服務綁定到該服務。通過這種方式,您可以確保該服務將在該活動未被銷燬之前存在。

我可以從片段連接看到兩個主要優點:

  1. 服務連接是異步的,所以裏面的片段你從來沒有真正確保您從活動獲得的服務是不爲空。這將導致您至少進行一些空指針檢查以及一些在創建和服務連接時都刷新片段的機制(因此,無論哪個先發生,您都可以確保顯示數據)。
  2. 你不依賴於你的片段留下的特定活動。爲了從活動中獲得服務,我認爲你正在對活動特定的類進行轉換。你可以用像getBoundService這樣的方法創建一個像BoundActivity這樣的接口來從中獲得服務,但是我認爲考慮到第1點的優點,這是一個開銷。如果你有多個服務,會發生什麼。

UPDATE

這是顯示這是一個非常簡單的項目。 https://github.com/ena1106/FragmentBoundServiceExample

+0

是的,你的第一個理由是非常真實的!我總是得到NullPointerExceptions。特別是當第一個片段加載並且活動尚未綁定到服務時。感謝您發佈簡單的項目鏈接。我會立即嘗試綁定碎片。希望它有效! ;) – MDijkstra

0

我發現是可靠的唯一方法是將使用裝載機在Fragment

  1. 在片段創建Loader
  2. 使用Loader(集的contextactivityinitLoader處當調用片段的onCreate時)
  3. 將服務綁定到onStartLoading,使用ServiceConnection作爲服務綁定
  4. 任選在onStartLoading/onStopLoading
  5. onStopLoading