Xamarin.Forms MessagingCenter
發行-訂閱模式是一種訊息模式,發行者可以在不知道任何接收者 (稱為訂閱者) 的情況下傳送訊息。 同樣地,訂閱者可以在不知道任何發行者的情況下接聽特定訊息。
.NET 中的事件會實作發佈-訂閱模式,如果不需要鬆散結合,則元件之間的通訊層是最簡單且直接的方法,例如控件和包含它的頁面。 不過,發行者和訂閱者存留期會藉由物件參考彼此藕合,而訂閱者類型必須具有發行者類型的參考。 這可以建立記憶體管理問題,特別是當有短期物件訂閱靜態或長時間存留物件的事件時。 如果未移除事件處理常式,訂閱者將會由發行者中的參考保持運作,這樣可防止或延遲訂閱者的記憶體回收。
類別 Xamarin.FormsMessagingCenter
會實作發佈-訂閱模式,允許元件之間的訊息式通訊,這些元件無法依物件和型別參考連結。 此機制讓發行者和訂閱者不需彼此參考就能進行通訊,有助於減少兩者之間的相依性。
MessagingCenter
類別提供多點傳送的發行-訂閱功能。 這表示可以有多個發行單一訊息的發行者,而且可以有多個接聽相同訊息的訂閱者:
發行者會使用 MessagingCenter.Send
方法來傳送訊息,而訂閱者會使用 MessagingCenter.Subscribe
方法來接聽訊息。 此外,訂閱者也可以在必要時,使用 MessagingCenter.Unsubscribe
方法,取消訂閱訊息訂閱。
重要
在內部,MessagingCenter
類別會使用弱式參考。 這表示它將不會讓物件持續運作,並將允許它們進行記憶體回收。 因此,應該只有當類別不再希望收到訊息時,才需要取消訂閱訊息。
發行訊息
MessagingCenter
訊息為字串。 發行者會使用其中一個 MessagingCenter.Send
多載來通知訊息的訂閱者。 下列程式碼範例會發行 Hi
訊息:
MessagingCenter.Send<MainPage>(this, "Hi");
在此範例中,Send
方法會指定代表傳送者的泛型引數。 若要接收訊息,訂閱者也必須指定相同的泛型引數,表示它們正在接聽來自該傳送者的訊息。 此外,此範例會指定兩個方法引數:
- 第一個引數會指定傳送者執行個體。
- 第二個引數會指定訊息。
承載資料也可以與訊息一起傳送:
MessagingCenter.Send<MainPage, string>(this, "Hi", "John");
在此範例中,Send
方法會指定兩個泛型引數。 第一個是傳送訊息的類型,而第二個是要傳送的承載資料類型。 若要接收訊息,訂閱者也必須指定相同的泛型引數。 這會啟用多則訊息,這類訊息會共用一個訊息識別碼,但傳送不同的承載資料類型以供不同的訂閱者接收。 此外,此範例會指定第三個方法引數,表示要傳送給訂閱者的承載資料。 在此案例中,承載資料為 string
。
Send
方法將使用射後不理方法來發行訊息和任何承載資料。 因此,即使沒有任何訂閱者已註冊要接收訊息,也會傳送訊息。 在此情況下,會忽略已傳送的訊息。
訂閱訊息
訂閱者可以註冊,以使用其中一個 MessagingCenter.Subscribe
多載來接收訊息。 下列程式碼範例示範此作法的範例:
MessagingCenter.Subscribe<MainPage> (this, "Hi", (sender) =>
{
// Do something whenever the "Hi" message is received
});
在此範例中,Subscribe
方法會將 this
物件訂閱至 MainPage
類型所傳送的 Hi
訊息,並執行回呼委派以回應接收訊息。 指定為 Lambda 運算式的回呼委派可以是更新 UI、儲存一些資料或觸發一些其他作業的程式碼。
注意
訂閱者可能不需要處理已發行訊息的每個執行個體,而且這可由 Subscribe
方法中指定的泛型類型引數來控制。
下列範例示範如何訂閱包含承載資料的訊息:
MessagingCenter.Subscribe<MainPage, string>(this, "Hi", async (sender, arg) =>
{
await DisplayAlert("Message received", "arg=" + arg, "OK");
});
在此範例中,Subscribe
方法會訂閱 MainPage
類型所傳送的 Hi
訊息,其承載資料為 string
。 回呼委派會執行以回應接收這類訊息,其會在警示中顯示承載資料。
重要
方法所 Subscribe
執行的委派將會在使用 Send
方法發行訊息的相同線程上執行。
從訊息中取消訂閱
若訂閱者不想再接收訊息,則應從訊息中取消訂閱。 這會使用其中一個 MessagingCenter.Unsubscribe
多載來達成:
MessagingCenter.Unsubscribe<MainPage>(this, "Hi");
在此範例中,Unsubscribe
方法會從 MainPage
類型所傳送的 Hi
訊息中取消訂閱 this
物件。
包含承載資料的訊息應使用指定兩個泛型引數的 Unsubscribe
多載來取消訂閱:
MessagingCenter.Unsubscribe<MainPage, string>(this, "Hi");
在此範例中,Unsubscribe
方法會從 MainPage
類型所傳送的 Hi
訊息中取消訂閱 this
物件,其承載資料為 string
。