我想出了一些解决方案。我创建了一个名为 EventSubscriber 的类,它完全按照我的意愿行事。
public class EventSubscriber<T> : IEventSubscriber
{
#region Private members
private List<Tuple<T, Func<T, bool>>> Subscribtions { get; set; }
private ConcurrentDictionary<int, Func<T, bool>> WaitingObjectSubscribtions { get; set; }
#endregion
public EventSubscriber()
{
Subscribtions = new List<Tuple<T, Func<T, bool>>>();
WaitingObjectSubscribtions = new ConcurrentDictionary<int, Func<T, bool>>();
}
#region Subscribe
public void Subscribe(T adapter, Func<T, bool> function)
{
lock (Subscribtions)
{
Subscribtions.Add(new Tuple<T, Func<T, bool>>(adapter, function));
}
}
public int Subscribe(Func<T, bool> function)
{
lock (WaitingObjectSubscribtions)
{
int id = WaitingObjectSubscribtions.Count;
WaitingObjectSubscribtions.TryAdd(id, function);
return id;
}
}
#endregion
#region Unsubscribe
public void UnSubscribe(Tuple<T, Func<T, bool>> item)
{
lock (Subscribtions)
{
Subscribtions.Remove(item);
}
}
public void UnSubscribe(int id)
{
lock (WaitingObjectSubscribtions)
{
Func<T, bool> func;
WaitingObjectSubscribtions.TryRemove(id, out func);
}
}
public void UnSubscribeAll()
{
lock (Subscribtions)
{
Subscribtions.Clear();
}
WaitingObjectSubscribtions.Clear();
}
#endregion
#region Call Subscribed
public void CallSubscribed()
{
lock (Subscribtions)
{
foreach (var item in Subscribtions)
{
(var adapter, var function) = item;
if (!function(adapter))
{
Log.Debug("[EventSubscriber]", "Failed to notify adapter, will be automatically unsubscribed from this event");
UnSubscribe(item);
}
}
}
}
public void CallSubscribedWith(T adapter)
{
foreach (var id in WaitingObjectSubscribtions.Keys)
{
var function = WaitingObjectSubscribtions[id];
try
{
if (!function(adapter))
{
Log.Debug("[EventSubscriber]", "Failed to execute function");
UnSubscribe(id);
}
}
catch (Exception)
{
Log.Debug("[EventSubscriber]", "Failed to execute function");
UnSubscribe(id);
}
}
}
#endregion
}
为了管理应用内使用的多个 EventSubscribed,我创建了一个静态类,可访问每个 Activity 或 Fragment,其中包含所有需要的事件:
public static class EventBoard
{
#region Products and Favorites
public static EventSubscriber<SwipeRefreshLayout> FinishedLoadingProducts = new EventSubscriber<SwipeRefreshLayout>();
public static EventSubscriber<List<Product>> SuccessfullyLoadedProducts = new EventSubscriber<List<Product>>();
public static EventSubscriber<RecyclerView.Adapter> UnsuccessfullyLoadedProducts = new EventSubscriber<RecyclerView.Adapter>();
//Search
public static EventSubscriber<SwipeRefreshLayout> FinishedLoadingProductsForSearch = new EventSubscriber<SwipeRefreshLayout>();
public static EventSubscriber<RecyclerView.Adapter> SuccessfullyLoadedProductsForSearch = new EventSubscriber<RecyclerView.Adapter>();
public static EventSubscriber<RecyclerView.Adapter> UnsuccessfullyLoadedProductsForSearch = new EventSubscriber<RecyclerView.Adapter>();
public static EventSubscriber<RecyclerView.Adapter> SearchNotFound = new EventSubscriber<RecyclerView.Adapter>();
//favorites
public static EventSubscriber<LocalProduct> ConfirmNewFavoriteEvent = new EventSubscriber<LocalProduct>();
public static EventSubscriber<LocalProduct> ConfirmRemoveFavoriteEvent = new EventSubscriber<LocalProduct>();
public static EventSubscriber<LocalProduct> NewFavoriteEvent = new EventSubscriber<LocalProduct>();
public static EventSubscriber<LocalProduct> RemoveFavoriteEvent = new EventSubscriber<LocalProduct>();
public static EventSubscriber<List<LocalProduct>> SetFavoritesEvent = new EventSubscriber<List<LocalProduct>>();
#endregion
}
因此,基本上,如果创建了一个新活动,它可以订阅其偏好的 EventSubscriber。此外,它可以提供一个接收任何类型对象的函数,因此它可以尽可能灵活。
唯一引起我关注的事情是,确保在 Activity 或 Fragment View 被销毁时取消订阅事件,因为它们可能是内存泄漏的良好来源。