AndroidThreadingInterface.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. using System;
  2. using System.Threading;
  3. using Android.OS;
  4. using Avalonia.Platform;
  5. using Avalonia.Reactive;
  6. using Avalonia.Threading;
  7. using App = Android.App.Application;
  8. namespace Avalonia.Android
  9. {
  10. internal sealed class AndroidThreadingInterface : IPlatformThreadingInterface
  11. {
  12. private Handler _handler;
  13. private static Thread s_uiThread;
  14. public AndroidThreadingInterface()
  15. {
  16. _handler = new Handler(App.Context.MainLooper);
  17. }
  18. public void RunLoop(CancellationToken cancellationToken) => throw new NotSupportedException();
  19. public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick)
  20. {
  21. if (interval.TotalMilliseconds < 10)
  22. interval = TimeSpan.FromMilliseconds(10);
  23. var stopped = false;
  24. Timer timer = null;
  25. timer = new Timer(_ =>
  26. {
  27. if (stopped)
  28. return;
  29. EnsureInvokeOnMainThread(() =>
  30. {
  31. try
  32. {
  33. tick();
  34. }
  35. finally
  36. {
  37. if (!stopped)
  38. timer.Change(interval, Timeout.InfiniteTimeSpan);
  39. }
  40. });
  41. },
  42. null, interval, Timeout.InfiniteTimeSpan);
  43. return Disposable.Create(() =>
  44. {
  45. stopped = true;
  46. timer.Dispose();
  47. });
  48. }
  49. private void EnsureInvokeOnMainThread(Action action) => _handler.Post(action);
  50. public void Signal(DispatcherPriority prio)
  51. {
  52. EnsureInvokeOnMainThread(() => Signaled?.Invoke(null));
  53. }
  54. public bool CurrentThreadIsLoopThread
  55. {
  56. get
  57. {
  58. if (s_uiThread != null)
  59. return s_uiThread == Thread.CurrentThread;
  60. var isOnMainThread = OperatingSystem.IsAndroidVersionAtLeast(23)
  61. ? Looper.MainLooper.IsCurrentThread
  62. : Looper.MainLooper.Thread.Equals(Java.Lang.Thread.CurrentThread());
  63. if (isOnMainThread)
  64. {
  65. s_uiThread = Thread.CurrentThread;
  66. return true;
  67. }
  68. return false;
  69. }
  70. }
  71. public event Action<DispatcherPriority?> Signaled;
  72. }
  73. }