在mono for android中异步加载图像时出现问题

在mono for android中异步加载图像时出现问题,android,asynchronous,mono,xamarin.android,Android,Asynchronous,Mono,Xamarin.android,我开始为Android开发一个新的mono应用程序,它需要我从远程服务器加载大量图像。为了做到这一点,我编程了一个视图,我可以插入一个布局,它加载在背景中的图像。在我将它用于ListView的适配器之前,它工作得非常好,这也是我主要计划使用它的地方。应用程序加载一些图像而不是其他图像,并且将它们加载到错误的位置。一旦您滚动列表,它就会开始正确加载图像,但显示的第一个图像不完整且错误。我尝试了不同的策略来运行后台进程asynctask、线程池等,但都有相同的问题。代码如下: using Syste

我开始为Android开发一个新的mono应用程序,它需要我从远程服务器加载大量图像。为了做到这一点,我编程了一个视图,我可以插入一个布局,它加载在背景中的图像。在我将它用于ListView的适配器之前,它工作得非常好,这也是我主要计划使用它的地方。应用程序加载一些图像而不是其他图像,并且将它们加载到错误的位置。一旦您滚动列表,它就会开始正确加载图像,但显示的第一个图像不完整且错误。我尝试了不同的策略来运行后台进程asynctask、线程池等,但都有相同的问题。代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Util;
using System.Net;
using Android.Graphics;
using ListViewExample;
using System.Threading;

namespace klvpn.components
{
    public class WebImageView : RelativeLayout
    {
        ImageView theImage;
        TextView waitingTxt;
        Activity context;
        Uri imageUri;
        WebClient wc;

        public WebImageView(Context context, IAttributeSet attrs) :
            base(context, attrs)
        {
            this.context = context as Activity;

            this.SetBackgroundColor(Android.Graphics.Color.Black);
            this.SetGravity(GravityFlags.Center);
            waitingTxt = new TextView(context);
            waitingTxt.SetText("...", TextView.BufferType.Normal);
            AddView(waitingTxt, new LayoutParams(LayoutParams.WrapContent, LayoutParams.WrapContent));

        }

        public void SetImageSize(int width, int height)
        {
            LayoutParameters.Width = width;
            LayoutParameters.Height = height;
        }

        public void SetImageUriStr(string uriStr)
        {
            imageUri = new Uri(uriStr);

            if (theImage == null)
            {
                theImage = new ImageView(context);
                AddView(theImage, 0);
            }
            wc = new WebClient();
            wc.DownloadDataCompleted += new DownloadDataCompletedEventHandler(wc_DownloadDataCompleted);
            wc.DownloadDataAsync(imageUri);
        }

        void wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                context.RunOnUiThread(() =>
                {               
                    theImage.SetImageResource(Resource.Drawable.noImage_x);                  
                    string error = "URI:" + imageUri.OriginalString + "\n" + e.Error.Message;
                    Log.Error("WebImageView", error);
                });
            }
            else
            {
                Bitmap bmp = BitmapFactory.DecodeByteArray(e.Result, 0, e.Result.Length);
                context.RunOnUiThread(() =>
                {
                    theImage.SetImageBitmap(bmp);
                });
            }
            wc = null;
        }

        protected override void OnDetachedFromWindow()
        {
            base.OnDetachedFromWindow();
            if (wc != null)
            {
                wc.CancelAsync();
            }

        }


    }
}
适配器的GetView方法如下所示:

public override View GetView(int position, View convertView, ViewGroup parent)
        {
            var item = this.Episodes[position];
            var view = convertView;
            if (convertView == null || !(convertView is LinearLayout))
            {
                view = context.LayoutInflater.Inflate(Resource.Layout.EpisodeItem, parent, false);
            }

            var imageItem = view.FindViewById<WebImageView>(Resource.Id.imageItem);
            var textTop = view.FindViewById<TextView>(Resource.Id.textTop);
            var textBottom = view.FindViewById<TextView>(Resource.Id.textBottom);

            //imageItem.SetImageResource(item.Image);
            imageItem.SetImageSize(100, 36);
            imageItem.SetImageUriStr(item.ImageUri);
            textTop.SetText(item.Name, TextView.BufferType.Normal);
            textBottom.SetText(item.Description, TextView.BufferType.Normal);

            return view;

        }
有没有办法解决这个问题?我在MonoTouch中使用了这种策略,这非常好,因为图像下载是封装的,用户不必等到所有内容加载后才能看到一些内容


谢谢

我建议使用图书馆:
它非常简单,集成速度也很快。

谢谢Anis,这个库看起来很棒。不幸的是,将Java库绑定到C仍然不是那么容易。如果Xamarin的人能试一试,那就太好了,因为它看起来真的很有用。它比以前容易多了,你看过吗