AndroidThreadingInterface.cs 2.3 KB

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