在我的应用中,我使用了RV。这是它的重载适配器:
private async void SetContent(PhotoViewHolder vh, int position) {
await SetContentAsync(vh, position);
}
private async Task SetContentAsync(PhotoViewHolder vh, int position)
{
string SongName = "";
string ArtistName = "";
Bitmap bitmap = null;
byte[] data = null;
RequestOptions requestOptions = null;
try
{
reader.SetDataSource(mp3Obj[position].Mp3Uri);
}
catch
{
Toast.MakeText(ctx, "ERROR 77s9", ToastLength.Short).Show();
}
// await Task.Run(() => // cause problems with the reload
// {
SongName = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyTitle);
ArtistName = reader.ExtractMetadata(MediaMetadataRetriever.MetadataKeyArtist);
data = reader.GetEmbeddedPicture();
if (data != null)
{
try
{
bitmap = BitmapFactory.DecodeByteArray(data, 0, data.Length);
requestOptions = new RequestOptions();
requestOptions.InvokeDiskCacheStrategy(DiskCacheStrategy.None);
// requestOptions.SkipMemoryCache(true);
requestOptions.CircleCrop();
requestOptions.CenterInside();
requestOptions.FitCenter();
requestOptions.OptionalCircleCrop();
ConvertBitmapToBackground(bitmap, vh, data); // Set As Backgorund, blurry and black ( just sets the variable)
}
catch
{
Toast.MakeText(ctx, "ERROR 034c", ToastLength.Short).Show();
}
}
//});
((Activity)ctx).RunOnUiThread(() =>
{
vh.SongName.SetTypeface(tf, TypefaceStyle.Normal);
vh.AristName.SetTypeface(tf, TypefaceStyle.Normal);
vh.SongName.Text = SongName;
vh.AristName.Text = ArtistName;
try
{
if (data != null)
{
Glide
.With(ctx)
.Load(data)
.Apply(requestOptions)
.Into(vh.CoverArt);
}
else // because recycler items inherit their shit and if it is altered it just shows views were there shouldnt be any ...
{
vh.CoverArt.SetImageResource(Resource.Drawable.btn_musicalnote);
vh.dr = null;
}
}
catch {
Toast.MakeText(ctx, "ERROR 034c", ToastLength.Short).Show();
}
});
}
如您所见,对数据进行解码的部分以前使用的是异步方法,不会阻塞UI线程。但是,这导致加载时出现问题。在繁重的工作中,物品的信息有误,物品翻了一番,有时甚至被绊倒了。通过删除异步任务并将其全部同步来解决了该问题。但是,这会使整个应用变得迟钝。
如何在RV中正确使用asnyc任务而不弄乱项目?
答案 0 :(得分:0)
您的问题在这里:
private async void SetContent(PhotoViewHolder vh, int position)
{
await SetContentAsync(vh, position);
}
problems with async void
之一是调用代码不知道该方法何时完成。据您的RV所知,它要求您的代码设置内容,然后返回代码,因此它确定它具有要获取的任何内容。
这是每个UI框架的基本问题:当计算机/设备需要显示某些内容时,它需要显示 now 。显示必须的数据必须是同步可用的。
那么,我们如何将其与从I / O加载数据的必要性以及I / O应该异步的观念相协调呢?
一种常见的模式是(同步)加载占位符数据。 “正在加载...”消息或微调框或其他内容。相同的代码也开始异步加载实际数据。当数据到达时(即I / O完成),然后(同步)更新 UI来显示真实数据。
您可能会发现我的article on asynchronous data binding有用。它采用Placeholder Data模式并将其应用于数据绑定UI框架(WPF,Xamarin等)。我认为您使用的是较低级别的Android UI API,因此代码不会直接相关,但是您应该可以执行类似的操作。生成的代码将比使用数据绑定更为冗长,但是应该应用相同的概念和模式。