1

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

  • 公共覆盖异步无效ViewAppeared()
  • 公共覆盖异步无效ViewAppearing()
  • 公共覆盖无效 ViewDisappearing()
  • 公共覆盖无效 ViewDisappeared()
  • 公共覆盖无效 ViewDestroy(bool viewFinishing)

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

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

2)如果是这样,我们必须遵循什么方法,当应用程序移动到前台/后台时我们需要执行一些操作(如停止计时器)?我们是否应该有两种实现,一种用于 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);
    }

基类:

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 上调用

4

1 回答 1

2

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

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;
        }

安卓

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

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

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

就我而言。我有一个共同的活动,它保留了所有片段的视图。因此,我在常见活动中添加了此代码。不确定你的情况是如何使用的。但实施将是相似的。

于 2021-04-27T15:55:16.090 回答