尝试从SQLite数据库加载图像时,Android ListView图像闪烁

时间:2015-04-13 15:11:53

标签: android image sqlite android-listview

我实施了ListView来显示SQLite Database中的一些项目。其中每个都包含Image和一些Data

我希望我的ListView工作得更快,即使它包含数千行数据。所以我试图实现一些我注意到的优化。以下是structure的基本CustomCursorAdapter

Class CustomCursorAdapter extends CursorAdapter
{
    Cursor cursor;
    public CustomCursorAdapter(..., Cursor _cursor)
    {
        cursor = _cursor;
    }

    public void bindView(View _view, Context _context, Cursor _cursor)
    {
        if( view.getTage() == null)
        {
            //create and initialize a new holder and set it to view tag.
            holder = new Holder();
            ...
            ...
            holder.imageView = (ImageView) view.findViewById(R.id.image);
            holder.imageView.setImageDrawable(defaultDrawable);

            view.setTag(holder);
        }

        String mediaID = _cursor.getString("media_id");

        //create an asyncTask to load the image from database
        new MediaLoader(context, holder.imageView).execute(mediaID);
    }

    private class MediaLoader extends AsyncTask<String, Void, Media>
    {
        private Context context;
        private final WeakReference <ImageView> imageViewReference;

        public MediaLoader(Context _context, ImageView _imageView)
        {
            context = _context;
            imageViewReference = new WeakReference<ImageView>(_imageView);
        }

        protected Media doInBackground(String... args)
        {
            String _mediaID = args[0];  
            return MediaDataManager.getInstance(_context).getMediaObjectForListAdapter(_mediaID);
        }

        protected void onPostExecute(final Media _media)
        {
            super.onPostExecute(_media);

            if( imageViewReference != null )
            {
                ImageView _imageView = imageViewReference.get();

                if(_imageView != null)
                {
                    if( _media != null && _media.getImage() != null )
                    {
                        _imageView.setImageBitmap(_media.getImage());
                    }
                    else
                    {
                        _imageView.setImageDrawable(defaultDrawable);
                    }
                }
            }
        }
    }//Media Loader ends.
}//Custom Cursor Adapter Ends.

使用这种方法,图像的加载时间对我来说似乎没问题。

但是在某些Android设备(低配置设备)中,我遇到了image flickering。出于某种原因,在scrollingloading期间,我注意到图像在整个列表中不断变化。但是,每行中保留的最终图像始终是correct

修改 逐个加载图像对我来说不是问题。但是在显示正确的图像之前显示一些不相关的图像是我唯一关注的问题。

通过搜索我找不到任何有用的资源。非常感谢任何形式的帮助。

1 个答案:

答案 0 :(得分:1)

让我们假设您的Cursor中有100行。并且,我们假设这是一个非常短的ListView,其中只有2行可见。而且,让我们假设在ListView中加载适配器后,用户会浏览整个列表。

您的代码将执行的操作是:

  • 分叉 100 AsyncTask个实例,在Android 3.2+上,它们一次只能执行一个(除非targetSdkVersion相当低)

  • 下载 100 图片

  • 100 图片中的每一个放入行中

所有这一切,对于你只需要2张图片的情况,最后的那些。

这就是为什么你真的应该考虑使用现有的库来处理这类事情,比如Picasso,你可以插入逻辑来将值拉出......好吧,无论你的图像实际存储在哪里。这些类型的库已经处理了这些情况。

如果你坚持自己实现这个,你将需要添加智能,以实现如果用户滚动列表并且我们正在回收一行,我们不再需要先前与该行绑定的任务。取消这些并排队任务以下载您需要的内容。另外,请考虑在API Level 11+上使用executeOnExecutor(),因此其中一些将并行运行。