Syntax
Syntax

Reputation: 2197

Xamarin BeginInvokeOnMainThread without Xamarin.Forms

Sorry for what I'm sure will turn out to be a very stupid question..

I am using Android UI not Xamarin Forms for the presentation layer in my Xamarin app, but I want to use the Activity.RunOnUIThread (from Android), which all Xamarin docs suggests is Device.BeginInvokeOnMainThread (from the Xamarin.Forms) project. Obviously I don't have this available since I don't have a reference on the xamarin.forms project.

Where do I find the run-on-ui-thread mechanism in Xamarin if I don't want to use Forms?

Upvotes: 4

Views: 4775

Answers (3)

Sven-Michael Stübe
Sven-Michael Stübe

Reputation: 14760

If you want to do this from your PCL / shared code and everywhere else in your project. You have two options doing this.

Cross platform way, using the native mechanisms

  • add this to PCL

    public class InvokeHelper
    {
        public static Action<Action> Invoker;
    
        public static void Invoke(Action action)
        {
            Invoker?.Invoke(action);
        }
    }
    
  • add this to iOS (e.g. AppDelegate)

    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
    {
        // ...
    
        InvokeHelper.Invoker = InvokeOnMainThread;
        return true;
    }
    
  • add this to Android (e.g. your application 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);
            };
        }
    }
    

And then you can call from your shared code

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

Complete cross platform way

You can implement InvokeHelper cross platform, too.

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

Upvotes: 6

SushiHangover
SushiHangover

Reputation: 74209

Android:

Android Activitys have a RunOnUiThread method that you can use:

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

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

iOS:

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

Upvotes: 10

Luis Beltran
Luis Beltran

Reputation: 1704

Here you have an example obtained from the 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");
  }
}

Basically, if you want to run more than one line of code, you can do this:

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

source

Upvotes: 1

Related Questions