Android 异步获取映像将执行错误

Android 异步获取映像将执行错误,android,asynchronous,xamarin,android-adapter,android-bitmap,Android,Asynchronous,Xamarin,Android Adapter,Android Bitmap,在Xamarin中,我有一个GridView适配器,它为每个GridView项目设置图像。此GridView适配器作为ViewPager的一部分从片段加载 每个GridView项都有一个显示图像的ImageView。我有一些代码可以在同步下载图像时正确显示图像,但是不能异步下载 这是我的密码: public override View GetView (int position, View convertView, ViewGroup parent) { View view = conv

Xamarin
中,我有一个
GridView
适配器,它为每个
GridView
项目设置图像。此
GridView
适配器作为
ViewPager
的一部分从
片段加载

每个
GridView
项都有一个显示图像的
ImageView
。我有一些代码可以在同步下载图像时正确显示图像,但是不能异步下载

这是我的密码:

public override View GetView (int position, View convertView, ViewGroup parent)
{
    View view = convertView;
    if (view == null)
        view = context.LayoutInflater.Inflate(Resource.Layout.GridViewWithImageAndTextItem, gridView, false);
    imgIcon =  view.FindViewById<ImageView> (Resource.Id.image);
    if (gridViewtems[position].useResourceAsThumbnail) 
    {
        imgIcon.SetImageResource (gridViewtems[position].imageResourceId);
    } else {
        //Code that does work
        imgIcon.SetImageBitmap (GetImageBitmapFromUrl (gridViewtems[position].thumbNailWebAddress));
        //Code that does not work
        DownloadAsyncBitmap (gridViewtems[position].thumbNailWebAddress, imgIcon);
    }
    view.FindViewById<TextView> (Resource.Id.myImageViewText).Text = gridViewtems[position].text;
    return view;
}

async void DownloadAsyncBitmap(string url, ImageView imageView)
{
    var webClient = new WebClient ();
    var uri = new Uri (url);
    byte[] bytes = null;
    try
    {
        bytes = await webClient.DownloadDataTaskAsync(uri);
    }
    catch(TaskCanceledException){
        Console.WriteLine ("Task Canceled!");
        return;
    }
    catch(Exception e){
        Console.WriteLine (e.ToString());
        return;
    }

    Bitmap bitmap = await BitmapFactory.DecodeByteArrayAsync (bytes, 0, bytes.Length);
    imageView.SetImageBitmap (bitmap);
}

private Bitmap GetImageBitmapFromUrl(string url)
{
    Bitmap imageBitmap = null;

    using (var webClient = new WebClient())
    {
        var imageBytes = webClient.DownloadData(url);
        if (imageBytes != null && imageBytes.Length > 0)
        {
            imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
        }
    }

    return imageBitmap;
}
这段精确的代码在我的另一个应用程序中有效,但在谷歌地图的这个应用程序中不起作用。有没有我错过的许可证

可以帮我异步设置图像吗

提前谢谢

编辑

感谢您提供的资源,我已经阅读了它,现在了解了有关async和Wait运算符的更多信息

这是我目前的代码:

async Task<Bitmap> DownloadBitmapAsync(string url)
{
    var webClient = new HttpClient ();
    var uri = new Uri (url);
    byte[] bytes = null;

    try
    {
        bytes = await webClient.GetByteArrayAsync(uri);
    }
    catch(TaskCanceledException){
        Console.WriteLine ("Task Canceled!");
        return null;
    }
    catch(Exception e){
        Console.WriteLine (e.ToString());
        return null;
    }

    Bitmap bitmap = await BitmapFactory.DecodeByteArrayAsync (bytes, 0, bytes.Length);
    return (bitmap);
}
GridView
显示,但是没有一个
ImageView
对象包含任何图像


我的代码正确吗?

ImageView是一个视图,只能在UI线程上操作。不确定这是否解决了您的问题:

((Activity)Context).RunOnUiThread (() => {imageView.SetImageBitmap (bitmap);} );

您以错误的方式使用异步等待

首先,您不应该从异步任务返回“void”。 因此,您的DownloadAsyncBitmap(专有名称约定为DownloadBitmapAsync)必须返回Task(相当于void),或者更好的是返回Task

其次,你以错误的方式调用你的任务。有一种方法名为“async all-way”,它意味着您应该将任务一直返回到顶级接口方法(command、clickEvent或getView)。如果此事件返回
void
则异步运行任务非常简单:

public async override void OnStart()
{
    await DoSomethingAsync();
}
您应该理解,异步等待只是围绕任务和连续性的语法糖。 因此,如果您的方法无法返回
void
(如GetView),则可以使用ContinueWith构造

在您的情况下,从GetView启动异步任务的正确方法是:

DownloadAsyncBitmap(gridViewtems[position].thumbNailWebAddress)
    .ContinueWith(continuation => { imageView.SetImageBitmap (continuation.Result); });
我建议您学习async,再等一会儿

public async override void OnStart()
{
    await DoSomethingAsync();
}
DownloadAsyncBitmap(gridViewtems[position].thumbNailWebAddress)
    .ContinueWith(continuation => { imageView.SetImageBitmap (continuation.Result); });