【问题标题】:Is there any app events on Xamarin.Android?Xamarin.Android 上是否有任何应用事件?
【发布时间】:2020-09-07 22:36:05
【问题描述】:

我有一个包含多个活动和片段的 Xamarin.Android 应用程序。该应用程序使用 SignalR,与 .net 核心后端 Web 应用程序连接。根据服务器调用的事件,有几个活动可能需要进行可视化修改。是否有任何类型的应用内事件可以在创建时订阅来处理这些所需的视觉更改?

例如: 我正在进行一项活动,该活动显示与出版物相关的 5 张图像,然后服务器发送通知,说明出版物已被编辑,因此图像已更改。在这种情况下,我希望 SignalR 客户端触发一些应用内事件,以更新此类已创建活动的更改图像。

【问题讨论】:

    标签: android xamarin xamarin.android


    【解决方案1】:

    我想出了一些解决方案。我创建了一个名为 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 被销毁时取消订阅事件,因为它们可能是内存泄漏的良好来源。

    【讨论】:

    • 感谢您的分享,请两天后接受您的答复。
    • 我只是想帮助遇到这个问题的人! Ty 为您提供支持
    【解决方案2】:

    要与实时服务器通信,您必须使用服务器包中的方法。通过研究,您可以使用HubConnection.On 方法。 Signalr 在您构建集线器时注册发送和接收方法:

    public class MyHub : Hub{
        public async Task Send(string user, string message){
            // Receive is the name of the listener method
            await Clients.All.SendAsync("Receive", user, message); 
        }
    }
    

    然后,在您的 Android 活动中,您可以使用 On 方法注册到侦听器方法的 HubConnection(假设您已发送有关已编辑图像的消息):

        myHubConnection.On<string, string>("Receive", (user, message) => 
        {
            /* change UI here */
        });
    

    【讨论】:

    • 是的,这确实是 SignalR 的工作方式,但我的问题是,是否有任何类型的应用内事件可用于触发订阅此事件之前的几个现有活动的 UI 更改创作
    猜你喜欢
    • 2019-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-05
    相关资源
    最近更新 更多