title: Xamarin Android: Exception thrown when adding new ImageView to ViewFlipper
body: <p>This is my first Xamarin project. I'm trying to create a simple slideshow app for Android. </p>
  
  <p>Here's the Main.axml code that hosts the ViewFlipper.</p>
  
  <pre><code>    &lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:orientation="vertical"&gt;
      &lt;ViewFlipper
          android:id="@+id/view_flipper"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"&gt;
      &lt;/ViewFlipper&gt;
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>Here's the Activity code.</p>
  
  <pre><code>namespace RS
  {
      [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
      [Activity (Label = "RS", MainLauncher = true)]
      public class MainActivity : Activity
      {
          protected override void OnCreate (Bundle bundle)
          {
              base.OnCreate (bundle);
  
              // Set our view from the "main" layout resource
              SetContentView (Resource.Layout.Main);
  
              StartSlideshow (this);
          }
  
          private Bitmap GetImageBitmapFromUrl(string url)
          {
              Bitmap imageBitmap = null;
  
              url = url.Replace("\"", "");
  
              using (var webClient = new WebClient())
              {
                  var imageBytes = webClient.DownloadData(url);
                  if (imageBytes != null &amp;&amp; imageBytes.Length &gt; 0)
                  {
                      imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
                  }
              }
  
              return imageBitmap;
          }
  
          private void StartSlideshow(Context ctx) 
          {   
              string[] slides = null;
              string url = "http://jsonplaceholder.typicode.com/photos";
              var httpReq = (HttpWebRequest)HttpWebRequest.Create (new Uri (url));
  
              httpReq.BeginGetResponse ((ar) =&gt; {
  
                  //Fetch the slides
                  var request = (HttpWebRequest)ar.AsyncState;
                  using (var response = (HttpWebResponse)request.EndGetResponse (ar))     {                           
                      var s = response.GetResponseStream ();
                      var j = (JsonArray)JsonArray.Load (s);
  
                      //Prepare the slides
                      slides = (from result in j
                          select result ["url"].ToString ()).ToArray ();
  
                      //Display the slides
                      ViewFlipper mViewFlipper = FindViewById&lt;ViewFlipper&gt;(Resource.Id.view_flipper);
  
                      for (int i = 0; i &lt; 10; i++) {
                          ImageView image = new ImageView(ctx);
                          image.SetImageBitmap(GetImageBitmapFromUrl(slides[i]));
                          try {
                              mViewFlipper.AddView(image);                            
                          } catch (Exception ex) {
                              Log.Error(ex.ToString(), "Couldn't add image to flipper");
                          }
                      }
  
                      mViewFlipper.AutoStart = true;
                      mViewFlipper.SetFlipInterval (2000);
                      mViewFlipper.StartFlipping ();
                  }
              } , httpReq);
  
          }
      }
  }
  </code></pre>
  
  <p>When I try to add a new ImageView to the ViewFlipper (after I get the list of images to display from the web service call), I get the following error.</p>
  
  <pre><code>ex  {Android.Util.AndroidRuntimeException: Exception of type 'Android.Util.AndroidRuntimeException' was thrown.
    at Android.Runtime.JNIEnv.CallVoidMethod (IntPtr jobject, IntPtr jmethod, Android.Runtime.JValue[] parms) [0x00063] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.12-series/163212a9/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:507 
    at Android.Views.ViewGroup.AddView (Android.Views.View child) [0x00043] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.12-series/163212a9/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Android.Views.ViewGroup.cs:1761 
    at RS.MainActivity+&lt;&gt;c__DisplayClass2.&lt;StartSlideshow&gt;b__0 (IAsyncResult ar) [0x000a0] in c:\Users\girish\Dropbox\Work\Rejini\android\RejiniSlider\RS\RS\MainActivity.cs:84 
    --- End of managed exception stack trace ---
  android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
      at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4039)
      at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:709)
      at android.view.View.requestLayout(View.java:12675)
      at android.view.View.requestLayout(View.java:12675)
      at android.view.View.requestLayout(View.java:12675)
      at android.view.View.requestLayout(View.java:12675)
      at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:268)
      at android.view.View.requestLayout(View.java:12675)
      at android.view.ViewGroup.addView(ViewGroup.java:3206)
      at android.widget.ViewAnimator.addView(ViewAnimator.java:182)
      at android.view.ViewGroup.addView(ViewGroup.java:3165)
      at android.view.ViewGroup.addView(ViewGroup.java:3145)
      at dalvik.system.NativeStart.run(Native Method)
  }   Android.Util.AndroidRuntimeException
  </code></pre>
  
  <p>Two questions:</p>
  
  <ol>
  <li><p>Is this the wrong way to build a dynamic slideshow in Android?</p></li>
  <li><p>How can I fix the error shown above?</p></li>
  </ol>
  
  <p>Thank you for helping out.</p>
  
  <p><strong>UPDATE:</strong>
  I updated the code to use async based on the answers from tomjen and Simon. Here's the updated method:</p>
  
  <pre><code>private Task&lt;Bitmap&gt; GetImageBitmapFromUrl(string url)
      {
          Task&lt;Bitmap&gt; imageBitmap = null;
  
          url = url.Replace("\"", "");
  
          RunOnUiThread ( () =&gt; {
              using (var webClient = new WebClient())
              {
                  var imageBytes = webClient.DownloadDataTaskAsync(url);
                  if (imageBytes != null) // &amp;&amp; imageBytes.Result.Length &gt; 0
                  {
                      try {
                          imageBitmap = BitmapFactory.DecodeByteArrayAsync(imageBytes.Result, 0, imageBytes.Result.Length);
                      } catch (Exception ex) {
                          Log.Error(ex.ToString(), "Couldn't download image");
                      }
                  }
              }
          });
  
          return imageBitmap;
      }
  </code></pre>
  
  <p>Unfortunately, I still get the same error. :(</p>