0

in my android app, I need to show the thumbnails of videos from a directory on sdcard. I create thumbnails with this code:

Bitmap bm = ThumbnailUtils.createVideoThumbnail(list.get(position).getPath()
    .substring(8, list.get(position).getPath().length()), MediaStore.Images.Thumbnails.MINI_KIND);

which takes time to create thumbnails. if I do it in async class, the position of the list gets repeated and shows wrong thumbnails.

how should I manage this?

Edit 1: async class:

public class CreateThumbnail extends AsyncTask<Integer, Void, Void> {

            Bitmap bm;

            @Override
            protected Void doInBackground(Integer... params) {
                bm = ThumbnailUtils.createVideoThumbnail(list.get(params[0]).getPath()
                        .substring(8, list.get(params[0]).getPath().length()), MediaStore.Images.Thumbnails.MINI_KIND);
                return null;
            }

            @Override
            protected void onPostExecute(Void aVoid) {
                super.onPostExecute(aVoid);
                imageView.setImageBitmap(bm);
            }
        }

Edit 2: getView method:

CheckBox checkBox;
        ImageView imageView;
        int pos = 0;
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            ImageEntity imageEntity = (ImageEntity) this.getItem(position);
            pos = position;

            if (convertView == null) {
                convertView = inflater.inflate(R.layout.item_grid_video, null);

                imageView = (ImageView) convertView.findViewById(R.id.image);
                checkBox = (CheckBox) convertView.findViewById(R.id.CheckBox1);
                convertView.setTag(new ViewHolder(imageView, checkBox));
                checkBox.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View v) {
                        CheckBox cb = (CheckBox) v;
                        ImageEntity imageEntity = (ImageEntity) cb.getTag();
                        imageEntity.setChecked(cb.isChecked());
                        if (imageEntity.isChecked()) {
                            txtCount.setText(String.valueOf(++count));
                            checkCounter(count);
                        } else {
                            txtCount.setText(String.valueOf(--count));
                            checkCounter(count);
                        }
                    }
                });
            }

            else {
                ViewHolder viewHolder = (ViewHolder) convertView.getTag();
                checkBox = viewHolder.getCheckBox();
                imageView = viewHolder.getImageView();
            }

            checkBox.setTag(imageEntity);

            checkBox.setChecked(imageEntity.isChecked());
            if (imageEntity.isVisibleCheckBoxes()) {
                checkBox.setVisibility(View.VISIBLE);
            } else {
                checkBox.setVisibility(View.INVISIBLE);
            }


            imageView.setImageBitmap(ThumbnailUtils.createVideoThumbnail(list.get(position).getPath()
                    .substring(8, list.get(position).getPath().length()), MediaStore.Images.Thumbnails.MINI_KIND));
            //new CreateThumbnail().execute(position);
            return convertView;
        }
Lithium
  • 529
  • 2
  • 11
  • 23
  • Please show us some more code. Please show us the getView method in the list view. – Ruchira Randana Mar 28 '16 at 08:28
  • Edited the main post – Lithium Mar 28 '16 at 08:37
  • Hi @Lithium, Are you trying to achieve something similar to the following? If so, then you may need to change some code. https://www.google.lk/imgres?imgurl=http://2.bp.blogspot.com/-m_BYkz7SJKU/UGzFxRU5WKI/AAAAAAAACwk/zh3sE3siqHU/s1600/Android%252BList%252BView%252BExample.PNG&imgrefurl=https://www.javacodegeeks.com/2012/10/android-listview-example-with-image-and.html&h=566&w=797&tbnid=SO8MmT5jtOrP_M:&docid=XyTJ9DsCkyU_9M&ei=qe_4VqGlOtDHuATB2rHYCw&tbm=isch&ved=0ahUKEwjhney3_-LLAhXQI44KHUFtDLsQMwgtKBEwEQ – Ruchira Randana Mar 28 '16 at 08:49
  • Hi @RuchiraRandana. Yes I'm trying to make something like that. what codes should I change? – Lithium Mar 28 '16 at 09:00

2 Answers2

1

Here is my suggested approach.

Call the CreateThumbnail method from within getView method. You have to pass the index to the AsyncTask.

After processing the thumbnail and inside onPostExecute method, Get the View which represents the index passed. You can use this link on how to get the view from a listView by using the index.

Now you can set the image to the imageView which you got a reference to.

However, take care to only update if the listview index is visible.

In addition, you might need to cancel the AsyncTask when the user scrolls and the index items scrolls off the visible portion. Otherwise, you might continue doing too many background tasks.

Community
  • 1
  • 1
Ruchira Randana
  • 3,525
  • 1
  • 24
  • 23
  • thanks for your answer, But I'm a little confused! I pass the index to the async class but since the async class acts like threads the sent index changes while the previous process isn't completed yet. considering that the index not changing, how can I access imageView inside onPostExecute? finally, of course the user will do scrolling. if I cancel the asyncTask calling he would see nothing then. right? – Lithium Mar 28 '16 at 10:15
  • Hi Lithium. The listview item's index does not change. The problem is you are referring to a class variable named imageview. You cannot do that with a list since the getview method is called multiple times. You should pass the index of the listview item along to the async task. You should then use a method which I have given a link to get a reference to the correct imageview. – Ruchira Randana Mar 28 '16 at 10:35
0

Are you creating a copy of the list in your async code after the list has finished being written to?

If not (and your async task is instead holding a reference to the original list), perhaps the asynchronous processing starts before the list of (presumably directory contents) is fully populated?

Bit hard to tell without more of the code.

mdhvn
  • 76
  • 3