Reputation: 5488
I'm just starting experimenting with MonoDroid using Visual Studio.
Trying to download image from the web and display it in an ImageView control.
Unfortunately, some strange reason prevents the image from being displayed in the ImageView. Although the image appears to be downloaded successfully, the control remains blank.
Anything I'm doing wrong here?
The code is as follows:
private void DoClick(object sender, EventArgs e)
{
WebClient web = new WebClient();
web.DownloadDataCompleted += new DownloadDataCompletedEventHandler(web_DownloadDataCompleted);
web.DownloadDataAsync(new Uri(@"http://upload.wikimedia.org/wikipedia/commons/d/d9/Test.png"));
Toast.MakeText(this, "Image downloaded!", ToastLength.Short).Show();
}
void web_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
if (e.Error != null)
{
Toast.MakeText(this, e.Error.Message, ToastLength.Short).Show();
}
else
{
Bitmap bm = BitmapFactory.DecodeByteArray(e.Result, 0, e.Result.Length);
ImageView imgView = FindViewById<ImageView>(Resource.Id.MyImageView);
imgView.SetImageBitmap(bm);
}
}
With the Main.axml defined as follows:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/MyButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/Hello"
/>
<ImageView
android:id="@+id/MyImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_below="@+id/MyButton"/>
</LinearLayout>
Upvotes: 1
Views: 2927
Reputation: 10139
There are two problems I see here:
web_DownloadDataCompleted
method if you want it to show once the download completes.The main problem here is that you're trying to update the UI from a background thread. Since the download is asynchronous it is processed on a background thread, including your callback. However, you cannot make updates to the UI from a background thread. If you wrap the contents of that method in a call to RunOnUiThread()
, the code works as expected:
void web_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
if (e.Error != null)
{
RunOnUiThread(() =>
Toast.MakeText(this, e.Error.Message, ToastLength.Short).Show());
}
else
{
Bitmap bm = BitmapFactory.DecodeByteArray(e.Result, 0, e.Result.Length);
RunOnUiThread(() =>
{
ImageView imgView = FindViewById<ImageView>(Resource.Id.MyImageView);
imgView.SetImageBitmap(bm);
});
}
}
Upvotes: 4