8

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

我已经扩展BaseSubscription了一个bool,因为知道这个订阅需要在主线程上发送消息。现在我需要能够在订阅的实际实现中使用InvokeOnMainThread方法TypedInvoke

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

4

1 回答 1

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) ,也可以将静态方法作为静态方法调用。


笔记:

  • 如果您在“Apps”和“Services”/“BackgroundAgents”之间共享代码,则需要非常小心地检查错误情况 - 并不总是有可用的 UI 线程。

  • Android 特别特别 - UI 线程只能通过当前前台活动真正访问 - 目前 MvvmCross 在IMvxAndroidCurrentTopActivity服务中跟踪此(通过 Activity OnStart 和 OnResume 挂钩) - 但不能保证您将始终运行前台活动 - 例如如果您的代码曾经加载非 MvvmCross 活动,那么显然 MvvmCross 不会知道这些。

  • 您不应该保留对 Dispatcher 的引用 - 如果这样做,那么您可能会将 Android Activity 保留在内存中,超出其自然生命周期

  • 我想DoStuff也可以将其放入扩展方法中-也许我会在 v3 中添加它(https://github.com/slodge/MvvmCross/issues/150

于 2013-02-12T10:26:38.633 回答