Android BeginInvokeOnMainThread() should not possibly block. (#343)
authorAtsushi Eno <atsushieno@gmail.com>
Fri, 16 Sep 2016 21:05:29 +0000 (06:05 +0900)
committerJason Smith <jason.smith@xamarin.com>
Fri, 16 Sep 2016 21:05:29 +0000 (14:05 -0700)
Android.App.Activity.RunOnUiThread() does not always run the argument
Runnable asynchronously; actually it is run synchronously if current
thread is the UI thread [*1][*2]

Use Handler.Post() instead. (It is also used in Android.App.SyncContext[*3])

[*1] https://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)
[*2] http://stackoverflow.com/questions/33039600/android-runonuithread-not-async
[*3] https://github.com/xamarin/xamarin-android/blob/5777337/src/Mono.Android/Android.App/SyncContext.cs#L15

Xamarin.Forms.Platform.Android/Forms.cs

index a2a063c..c2dc770 100644 (file)
@@ -264,9 +264,7 @@ namespace Xamarin.Forms
 
                        public void BeginInvokeOnMainThread(Action action)
                        {
-                               var activity = Context as Activity;
-                               if (activity != null)
-                                       activity.RunOnUiThread(action);
+                               new Handler(Looper.MainLooper).Post(action);
                        }
 
                        public Ticker CreateTicker()