2013-02-12 39 views
8

我正在使用功能来扩展Messenger插件,这将使得在主线程上传递消息成为可能,而不是在后台线程上发生的所有事情。MvvmCross:在插件中使用InvokeOnMainThread

我已将BaseSubscription扩展为bool,以了解此订阅需要在主线程中发送消息。现在我需要能够在订阅的实际实现中使用TypedInvoke方法中的InvokeOnMainThread

当我在引用的MvvmCross程序集中看到Cirrious.MvvmCross.ViewModels.MvxMainThreadDispatchingObject包含InvokeOnMainThread方法时,所以问题是如何获取该对象以便可以调用该方法?

回答

5

获得UI线程保持最简单的方法是从MvxMainThreadDispatchingObject

如果继承层次结构不会让你,那么下一个最简单的方法是添加IMvxServiceConsumer标记接口,并再使用GetService<T>扩展方法:

public class MyClass 
    : MyBaseClass 
    , IMvxServiceConsumer 
{ 
    // ... 

    private bool DoStuff(Action stuff) 
    { 
     var dispatcherProvider = this.GetService<IMvxMainThreadDispatcherProvider>(); 
     var dispatcher = dispatcherProvider.Dispatcher; 
     if (dispatcher == null) { 
      return false; 
     } 

     return dispatcher.RequestMainThreadAction(action); 
    } 
} 

如果首选GetService<T>()静态方法也可以援引作为一个静态方法(如果你不希望使用IMvxServiceConsumer)。


注:

  • 如果您共享之间的“应用”和“服务” /“BackgroundAgents”你需要非常小心地检查错误条件码 - 没有永远一个可用的UI线程。

  • Android是尤为特别 - UI线程真的只能可以通过当前的前景活动访问 - 目前MvvmCross跟踪这(通过活动的OnStart和的onResume钩子)在IMvxAndroidCurrentTopActivity服务 - 但有没有保证,你将永远有运行的前台活动 - 例如如果你的代码加载非MvvmCross活动,那么显然MvvmCross不会知道这些。

  • 你不应该继续保留到Dispatcher引用 - 如果你这样做,那么你可能会拿着安卓活动在超出其自然寿命

  • 我想DoStuff内存可以被放入扩展方法太 - 也许我会补充说,在V3(https://github.com/slodge/MvvmCross/issues/150

+0

这仍然是最新的? – tofutim 2014-03-06 23:45:00

+1

从MvxMainThreadDispatchingObject继承我的工作(在我的MvvmCross插件之一的iOS中)。 – 2015-06-22 15:01:11

+0

你能提供一个关于如何调用DoStuff函数的例子吗?例如,显示加载顺序。谢谢。 – Ph0b0x 2017-06-29 17:39:43