Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/215.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从url异步加载图像以填充listview_C#_Android_Listview_Xamarin.android_Xamarin - Fatal编程技术网

C# 从url异步加载图像以填充listview

C# 从url异步加载图像以填充listview,c#,android,listview,xamarin.android,xamarin,C#,Android,Listview,Xamarin.android,Xamarin,我目前在异步映像加载以填充“无限”列表视图(从url加载数据并存储在自定义适配器中)方面遇到了一些问题。我找到了ImageView的扩展方法,基本上是端口到,但是原来的更新了很多,并且端口已经有9个月没有更新了。。。当我在我的自定义适配器中填充ImageView时,一切看起来都很好,速度也很快(我正在从非常快的服务器下载小的图像),但是在大约200个图像(每个15-20KB大小)之后,下载就停止了。我假设问题出在图像缓存中,但即使使用扩展中提供的“清理”方法,也没有任何变化。有人知道如何解决这个

我目前在异步映像加载以填充“无限”列表视图(从url加载数据并存储在自定义适配器中)方面遇到了一些问题。我找到了ImageView的扩展方法,基本上是端口到,但是原来的更新了很多,并且端口已经有9个月没有更新了。。。当我在我的自定义适配器中填充ImageView时,一切看起来都很好,速度也很快(我正在从非常快的服务器下载小的图像),但是在大约200个图像(每个15-20KB大小)之后,下载就停止了。我假设问题出在图像缓存中,但即使使用扩展中提供的“清理”方法,也没有任何变化。有人知道如何解决这个问题,或者有更好的解决方案吗?我曾尝试创建自己的“队列”,但它有另一种问题-当滚动listview时,任何新的ImageView都已经有了源图像,更改为正确的图像,但是快速滚动看起来非常糟糕。 这是我的密码:

我的自定义列表适配器中的GetView
public override View GetView(int位置、视图转换视图、视图组父视图)
{
//用新项填充适配器
如果(位置>=此._items.Count-1)
ThreadPool.QueueUserWorkItem(o=>this.LoadPage());
var项目=此项。_项目[位置];
视图=转换视图;
如果(视图==null)
视图=此。_context.LayoutInflater.Inflate(Resource.Layout.CustomRowView,null);
var imgUrl=string.Format(@)http://myserver.com/?action={0}&url={1},“get.缩略图”,item.Image.url);
//这是图像加载行
view.findviewbyd(Resource.Id.imageView1.SetUrlDrawable(imgUrl);
view.findviewbyd(Resource.Id.txtTitle).Text=item.Title;
view.findviewbyd(Resource.Id.txtYear).Text=item.Information.Year;
view.findviewbyd(Resource.Id.txtgree).Text=item.Information.Genre;
view.findviewbyd(Resource.Id.txtGrade).Text=item.Rating.Grade;
view.findviewbyd(Resource.Id.txtdovates).Text=string.Format(“({0})”,item.Rating.voates);
返回视图;
}
加载页函数
public void LoadPage()
{
OnUpdateAnimeListStart();//显示加载消息的事件
尝试
{
此.u items.FillListFromUrl(string.Format(“http://myserver.com/page/{0}/”,本页);
}
捕获(例外情况除外)
{
_context.RunOnUiThread(()=>
{
新建AlertDialog.Builder(_上下文)
.SetPositiveButton(“确定”,(发送方,参数)=>
{
Intent blankIntent=新Intent();
blankIntent.SetFlags(ActivityFlags.ClearTop);
int intPID=Android.OS.Process.MyPid();
Android.OS.Process.KillProcess(intPID);
})
.SetMessage(例如Message)
.SetTitle(“错误!”)
.Show();
});
}
这个;
_context.RunOnUiThread(()=>
{
_context.findviewbyd(Resource.Id.listView).InvalidateViews();
});
onUpdate animeListend();//隐藏加载消息的事件
}

这是我提到的另一种“队列”
公共类ImageDownloader
{
私有列表视图;
私有列表(url);;
私人活动——语境;
公共图像下载程序(活动上下文)
{
这._context=context;
这是。_queueImageViews=new List();
这是。_queueImageUrls=new List();
}
public void DownloadImage(ImageView imgView,字符串url)
{
此._queueImageViews.Add(imgView);
此._queueImageUrls.Add(url);
if(this._queueImageViews.Count==1)
这个;
}
私有void_startJob()
{
WebClient web=新的WebClient();
web.DownloadDataCompleted+=新的DownloadDataCompletedEventHandler(web\u DownloadDataCompleted);
DownloadDataAsync(新Uri(this._queueImageUrls[0]);
}
private void _removeFromeQueue(int index=0)
{
this._queueImageUrls.Remove(this._queueImageUrls[index]);
this._queueImageViews.Remove(this._queueImageViews[index]);
}
void web_DownloadDataCompleted(对象发送方,DownloadDataCompletedEventArgs e)
{
ImageView v=此项。_队列IMAGEVIEWS[0];
此._context.RunOnUiThread(()=>
{
位图bm=BitmapFactory.DecodeByteArray(e.Result,0,e.Result.Length);
v、 SetImageBitmap(bm);
});
这个。_从equeue()中移除;
如果(此._queueImageViews.Count>0)
这个;
}
}

提前谢谢。

解决了我的问题,这要感谢UrlImageViewHelper端口中的更多调试。 正如我所想,问题出在缓存中。背后的逻辑是将缓存项限制为特定数量(我不知道为什么,但它是硬编码的),如果达到限制,则需要从缓存中删除前几个项。这很好,但是实现仍然有一些bug。现在,我没有进行更多的调试和修复实现,而是将限制增加到5000(最初设置为100),但这只是修复此问题的临时方法。在将来,我可能会修复代码,因此它将删除缓存集合中的第一个项。这就是:

SoftReferenceHashTable
class 修正了这一行:
LRUCache缓存=新的LRUCache(100)
为此:
LRUCache缓存=新的LRUCache(5000)


此外,由于@Y2i的评论,我发现在
urlmageviewhelper
类中,在
seturldawable
方法中,下载是在不关闭internet连接的情况下实现的。也许这不是什么大问题,但我更愿意解决它。所以我
public override View GetView(int position, View convertView, ViewGroup parent)
{
    //Populating the adapter with new items
    if (position >= this._items.Count - 1)
        ThreadPool.QueueUserWorkItem(o => this.LoadPage());

    var item = this._items[position];
    View view = convertView;
    if (view == null)
        view = this._context.LayoutInflater.Inflate(Resource.Layout.CustomRowView, null);

    var imgUrl = string.Format(@"http://myserver.com/?action={0}&url={1}", "get.thumbnail", item.Image.Url);

    //Here is the image loading row
    view.FindViewById<ImageView>(Resource.Id.imageView1).SetUrlDrawable(imgUrl);

    view.FindViewById<TextView>(Resource.Id.txtTitle).Text = item.Title;
    view.FindViewById<TextView>(Resource.Id.txtYear).Text = item.Information.Year;
    view.FindViewById<TextView>(Resource.Id.txtGenre).Text = item.Information.Genre;
    view.FindViewById<TextView>(Resource.Id.txtGrade).Text = item.Rating.Grade;
    view.FindViewById<TextView>(Resource.Id.txtVotes).Text = string.Format("( {0} )", item.Rating.Votes);

    return view;
}
public void LoadPage()
{
    OnUpdateAnimeListStart(); //Event to display loading message
    try
    {
        this._items.FillListFromUrl(string.Format("http://myserver.com/page/{0}/", this._page));
    }
    catch(Exception ex)
    {
        _context.RunOnUiThread(() =>
        {
            new AlertDialog.Builder(_context)
                .SetPositiveButton("Ok", (sender, args) =>
                {
                    Intent blankIntent = new Intent();
                    blankIntent.SetFlags(ActivityFlags.ClearTop);
                    int intPID = Android.OS.Process.MyPid();
                    Android.OS.Process.KillProcess(intPID);
                })
                .SetMessage(ex.Message)
                .SetTitle("Error!")
                .Show();
        });
    }

    this._page++;
    _context.RunOnUiThread(() =>
    {
        _context.FindViewById<ListView>(Resource.Id.listView).InvalidateViews();
    });

    OnUpdateAnimeListEnd(); //Event to hide loading message
}
    public class ImageDownloader
    {
        private List<ImageView> _queueImageViews;
        private List<string> _queueImageUrls;
        private Activity _context;

        public ImageDownloader(Activity context)
        {
            this._context = context;
            this._queueImageViews = new List<ImageView>();
            this._queueImageUrls = new List<string>();
        }

        public void DownloadImage(ImageView imgView, string url)
        {
            this._queueImageViews.Add(imgView);
            this._queueImageUrls.Add(url);

            if (this._queueImageViews.Count == 1)
                this._startJob();
        }

        private void _startJob()
        {
            WebClient web = new WebClient();
            web.DownloadDataCompleted += new DownloadDataCompletedEventHandler(web_DownloadDataCompleted);
            web.DownloadDataAsync(new Uri(this._queueImageUrls[0]));
        }

        private void _removeFromeQueue(int index = 0)
        {
            this._queueImageUrls.Remove(this._queueImageUrls[index]);
            this._queueImageViews.Remove(this._queueImageViews[index]);

        }

        void web_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
        {
            ImageView v = this._queueImageViews[0];
            this._context.RunOnUiThread(() =>
            {
                Bitmap bm = BitmapFactory.DecodeByteArray(e.Result, 0, e.Result.Length);
                v.SetImageBitmap(bm);
            });
            this._removeFromeQueue();
            if (this._queueImageViews.Count > 0)
                this._startJob();
        }
    }
var client = new System.Net.WebClient();
var data = client.DownloadData(url);
System.IO.File.WriteAllBytes(filename, data);
return LoadDrawableFromFile(context, filename);
using (var client = new System.Net.WebClient())
{
    var data = client.DownloadData(url);
    System.IO.File.WriteAllBytes(filename, data);
    return LoadDrawableFromFile(context, filename);
}