Xamarin MvvmCross:iOS 如何监控应用程序已移至 foreground/background

Xamarin MvvmCross: iOS how to monitor the app has move to foreground/background

我有一个 MvvmCross 应用程序,我正在使用 MvvmCross ViewModel Lifecycle 函数来实现 视图出现、移动到背景和移动到前景时的某些操作:

这些功能在我的 Android 设备上运行良好。 但是对于 iOS 它们不会在应用程序移动到后台或前台时被触发 (虽然,除了 ViewDestroy,它们在 iOS 中的应用程序的屏幕之间导航时触发)

1)这是预期的行为,还是我遗漏了什么?

2)如果是这样,当应用程序移动到 foreground/background 时我们需要执行哪些操作(例如停止计时器),我们必须遵循什么方法? 我们是否应该有两种实现方式,一种用于 android,另一种用于 ios?我还尝试了 MvxBaseViewController 中的 ViewDidDisappear 方法, 当应用程序移至后台时,它仍未激活。 Xamarin/MvvmCross 中有一种方法可以挂接到本机 ios applicationDidEnterBackground?

编辑: 我试过 Ranjit 的回答,但订阅消息似乎有问题。这是我的测试代码:

AppDelegate.cs:

public override void DidEnterBackground(UIApplication application)
    {
        base.DidEnterBackground(application);
        var message = new LocationMessage(
            this,
            34
        );
        _messenger = Mvx.IoCProvider.Resolve<IMvxMessenger>();

        _messenger.Publish(message);
    }

基础class:

public abstract class GenericMvxViewModel : MvxViewModel
{
    private IMvxMessenger _messenger;
 
    protected GenericMvxViewModel()
    {
        // other stuff
        _messenger = Mvx.IoCProvider.Resolve<IMvxMessenger>();
        _messenger.Subscribe<LocationMessage>(OnLocationMessage);
    }

    protected virtual void OnLocationMessage(LocationMessage locationMessage){} 
}

视图模型:

public  class MyClassViewModel : GenericMvxViewModel
{
    protected override void OnLocationMessage(LocationMessage locationMessage)
    {
        Debug.WriteLine(locationMessage.Lat);
    }
}

消息在 AppDelegate.cs 中发布,但从未执行视图模型中的 OnLocationMessage 方法。

我也想知道如何正确取消订阅消息。 ViewDestroy 似乎是最自然的地方,但如前所述,它从未在 iOS

上被调用

您的代码应该可以工作。我在我的应用程序中使用了相同类型的功能,它工作正常

GenericMvxViewModel 代码

        private MvxSubscriptionToken _locationEventToken;

        public override void ViewAppeared()
        {
            SubscribeBaseLocationEvent();
            base.ViewAppeared();
        }

        public override void ViewDisappeared()
        {
            if (StaticStorage.IsApplicationInForeground)
            {
                UnSubscribeBaseLocationEvent();
            }
            base.ViewDisappeared();
        }

        public void SubscribeBaseLocationEvent()
        {
            if (_locationEventToken == null)
            {
                _locationEventToken = Messenger.Subscribe<LocationMessage>(OnLocationMessage);
            }
        }

        public void UnSubscribeBaseLocationEvent()
        {
            if (_locationEventToken != null)
            {
                Messenger.Unsubscribe<LocationMessage>(_locationEventToken);
                _locationEventToken = null;
            }
        }

AppDelegate 代码

  public override void DidEnterBackground(UIApplication application)
        {
            base.DidEnterBackground(application);
            StaticStorage.IsApplicationInForeground = false;
            _messenger.Publish(new LocationMessage( this, 34 ));
        }

        public override void WillEnterForeground(UIApplication application)
        {
            StaticStorage.IsApplicationInForeground = true;
        }

Android

 protected override void OnResume()
        {
            StaticStorage.IsApplicationInForeground = true;
            base.OnResume();
        }

        protected override void OnStop()
        {
            StaticStorage.IsApplicationInForeground = false;
            base.OnStart();
        }

当应用程序从一个视图移动到另一个视图时,我们需要取消订阅该事件。但不是当应用程序移动到后台时。因此,IsApplicationInForeground 标志将有助于解决 android 的这个问题。因为对于 android 当应用程序进入后台时 ViewDisappeared 将被调用。

以我为例。我有一个常见的 activity,它包含片段的剩余所有视图。所以,我添加了这个共同的代码activity。不确定您的情况如何使用。但实施将是相似的。