从异步任务填充列表会产生奇怪的结果

时间:2019-01-14 12:05:58

标签: android android-asynctask

在我的应用中,后台任务应该从电话中获取媒体文件,并显示其名称,艺术家及其封面(如果有)。

在UI线程上执行操作会导致应用非常滞后,但是,将此操作推送到异步任务中会很顺利,但有时会产生错误的结果。名称错误,或图像不正确。有时物品翻倍。我在这里录音了:

https://www.youtube.com/watch?v=SVAvY6X5yr0

我真的不知道我在做什么错,但是看起来很奇怪。这就是所有的样子:

private async Task SetContentAsync(PhotoViewHolder vh, int position)
{
    string SongName = "";
    string ArtistName = "";
    Bitmap bitmap = null;
    byte[] data = null;
    RequestOptions requestOptions = new RequestOptions();

    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.InvokeDiskCacheStrategy(DiskCacheStrategy.None);
                requestOptions.SkipMemoryCache(false);
                requestOptions.CircleCrop();
                requestOptions.CenterInside();
                requestOptions.FitCenter();

                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 stuff 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线程上设置内容。 这不好吗?

谢谢

编辑:

这是回收站视图的初始化功能:

    private void InitRecView()
    {

        if (ap.getFirstStart())
        {
            ShowTutorial(1);
            ap.saveFirstStart(false);
        }
        // Instantiate the adapter and pass in its data source:

        ImageView lnBg = (ImageView)FindViewById(Resource.Id.background_recView);

        mAdapter = new PhotoAlbumAdapter(GetSortedListWithAllSongs(), this, dbSeekObj, seekObj, mAudioManager, this, lnBg);

        // Get our RecyclerView layout:
        mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);

        // Plug the adapter into the RecyclerView:
        mRecyclerView.SetAdapter(mAdapter);
        mRecyclerView.SetItemViewCacheSize(50);
        mRecyclerView.DrawingCacheEnabled = true;
        mRecyclerView.DrawingCacheQuality = DrawingCacheQuality.High;

        mLayoutManager = new PreCachingLayoutManager(this);
        mLayoutManager.ItemPrefetchEnabled = true;
        mRecyclerView.SetLayoutManager(mLayoutManager);

这是PhotoViewHolder:

    public PhotoViewHolder(View itemView, List<MP3objectSmall> mp3Obj, Activity_Player act, MediaMetadataRetriever reader, DataBase db, List<SeekObj> seekObj, AudioManager audioManager, ImageView lnBg, Context ctx) : base(itemView)
    {
        // Locate and cache view references:
        SongName = itemView.FindViewById<TextView>(Resource.Id.textView);
        AristName = itemView.FindViewById<TextView>(Resource.Id.textView2);
        lnContainer = itemView.FindViewById<LinearLayout>(Resource.Id.linlay_cardview);
        CoverArt = itemView.FindViewById<ImageButton>(Resource.Id.musical_note);

        this.mp3Obj = mp3Obj;
        this.act = act;
        this.reader = reader;
        this.db = db;
        this.seekObj = seekObj;
        this.ctx = ctx;
        this.audioManager = audioManager;
        this.lnBg = lnBg;


        lnContainer.Click += delegate
        {
            int pos = AdapterPosition;
            ClickEvent(pos, AristName.Text, SongName.Text, CoverArt, lnBg);
        };
    }

0 个答案:

没有答案