没有 Xamarin.Forms 的 Xamarin BeginInvokeOnMainThread

Xamarin BeginInvokeOnMainThread without Xamarin.Forms

抱歉,我确定这会是一个非常愚蠢的问题..

我在我的 Xamarin 应用程序中使用 Android UI 而不是 Xamarin Forms 作为表示层,但我想使用 Activity.RunOnUIThread(来自 Android),所有 Xamarin 文档都建议使用 Device.BeginInvokeOnMainThread(来自 Xamarin.Forms)项目。显然我没有这个可用,因为我没有关于 xamarin.forms 项目的参考。

如果我不想使用 Forms,我在哪里可以找到 Xamarin 中的 运行-on-ui-thread 机制?

这里有一个例子来自 official documentation:

public class ThreadDemo : Activity
{
  TextView textview;

  protected override void OnCreate (Bundle bundle)
  {
      base.OnCreate (bundle);
      // Create a new TextView and set it as our view
      textview = new TextView (this);
      textview.Text = "Working..";
      SetContentView (textview);
      ThreadPool.QueueUserWorkItem (o => SlowMethod ());
  }

  private void SlowMethod ()
  {
      Thread.Sleep (5000);
      RunOnUiThread (() => textview.Text = "Method Complete");
  }
}

基本上,如果你想运行一行以上的代码,你可以这样做:

RunOnUiThread(()=>{
  MethodOne();
  MethodTwo();
});

source

Android:

Android Activity 有一个 RunOnUiThread 方法可以使用:

RunOnUiThread  ( () => {
    // manipulate UI controls
});

参考:https://developer.xamarin.com/api/member/Android.App.Activity.RunOnUiThread/p/Java.Lang.IRunnable/

iOS:

InvokeOnMainThread (delegate {  
    // manipulate UI controls
});

如果您想从您的 PCL / 共享代码和您项目中的其他任何地方执行此操作。您有两种选择。

跨平台方式,使用原生机制

  • 将此添加到 PCL

    public class InvokeHelper
    {
        public static Action<Action> Invoker;
    
        public static void Invoke(Action action)
        {
            Invoker?.Invoke(action);
        }
    }
    
  • 将此添加到 iOS(例如 AppDelegate)

    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
    {
        // ...
    
        InvokeHelper.Invoker = InvokeOnMainThread;
        return true;
    }
    
  • 将此添加到 Android(例如您的应用程序 class)

    [Application]
    class MainApplication : Application
    {
        protected MainApplication(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
        {
        }
    
        public override void OnCreate()
        {
            base.OnCreate();
            InvokeHelper.Invoker = (action) =>
            {
                var uiHandler = new Handler(Looper.MainLooper);
                uiHandler.Post(action);
            };
        }
    }
    

然后您就可以通过您的共享代码拨打电话了

InvokeHelper.Invoke(() => DoSomething("bla"));

完全跨平台方式

您也可以实现 InvokeHelper 跨平台。

public class InvokeHelper
{
    // assuming the static initializer is executed on the UI Thread.
    public static SynchronizationContext mainSyncronisationContext = SynchronizationContext.Current;

    public static void Invoke(Action action)
    {
        mainSyncronisationContext?.Post(_ => action(), null);
    }
}