Brando T.
Brando T.

Reputation: 163

Load Images in GridView in a Synchronization - Android

I have a question, I have a GridView in which I am loading images using a ImageView, these images it´s stored in the SD, for this I am using the Runnable class for loading. When it scrolling through the GridView the images are loaded in the box that corresponds (ImageView), and too in other tables, I'm making something like a list of albums of music, the image is loaded into an album, but also load in another and so on, how could you do to make synchronize?, ie if one charge, not be loaded into another

I hope me understand

thanks

PD: Sorry for my English

public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater) getContext().getSystemService("layout_inflater");
        v = vi.inflate(R.layout.listitemalbum, null);
    }

    bnSong = songs.get(position);
    if (bnSong != null) {
        coverAlbum = (ImageView) v.findViewById(R.id.imgCover);
        coverAlbum.setScaleType(ImageView.ScaleType.CENTER_CROP);

        if (bnSong.getAlbum() == null){
            coverAlbum.setBackgroundResource(R.drawable.mksong);
        }else{
            try {
                Runnable r = new Runnable() {
                    @Override
                    public void run() {
                        try{
                            Thread.sleep(1000);                                 
                            Storage storage = new Storage();                                
                            cover = storage.getOpenImagen(bnSong.getAlbum(), "ALBUM");
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                        coverAlbum.post(new Runnable() {
                            @Override
                            public void run() {
                                coverAlbum.invalidate();
                                coverAlbum.setImageBitmap(null);
                                if (cover != null){
                                    coverAlbum.setImageBitmap(cover);
                                }else {
                                    coverAlbum.setBackgroundResource(R.drawable.mksong);
                                }
                            }
                        });
                    }
                };
                new Thread(r).start();
            } catch (Exception e) {
                coverAlbum.setBackgroundResource(R.drawable.mksong);
            }
        }
    }
    return v;
}

Upvotes: 1

Views: 1225

Answers (2)

moveaway00
moveaway00

Reputation: 917

There is a library specifically for exactly your problem, released by the google team called "volley". It's pretty new though. Information here: https://developers.google.com/live/shows/474338138/.

For solving your problem without a library though: First, you should be using an android AsyncTask, and the executeOnExecutor(THREAD_POOL_EXECUTOR) method., over a runnable and thread. You're making a new thread for every view on screen, plus every time it's scrolled. If you really want to do this with runnables, use an ExecutorService to make a thread pool, and post your runnables there.

Now, the problem you're having is the image being overwritten, when a view is reused. What you need to do is to check, after downloading the image, that the item at the view position has the same album. This is often best done with a tag on the view.

public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
    LayoutInflater vi = (LayoutInflater) getContext().getSystemService("layout_inflater");
    v = vi.inflate(R.layout.listitemalbum, null);
}

final Song song = songs.get(position);
if (song != null) {
    final ImageView coverAlbum = (ImageView) v.findViewById(R.id.imgCover);
    coverAlbum.setScaleType(ImageView.ScaleType.CENTER_CROP); // Why not do this once, at inflation?

    final Album album = song.getAlbum();
    coverAlbum.setTag(album);        

    if (album == null){
        coverAlbum.setBackgroundResource(R.drawable.mksong);
    }else{
        // This should really be in a full class which extends AsyncTask
        AsyncTask<Album, Void, Bitmap> task = new AsyncTask<Album, Void, Bitmap>() {
            @Override
            public Bitmap doInBackground(Album... albums) {
                final Album album = albums[0];
                try{
                    Storage storage = new Storage();                                
                    return storage.getOpenImagen(album, "ALBUM");
                }catch (Exception e){
                    e.printStackTrace();
                    return null;
                }
            }

            @Override
            protected void onPostExecute(Bitmap cover) {
                final Album currentAlbum = (Album) coverAlbum.getTag();
                if(!album.equals(currentAlbum))
                    return;

                coverAlbum.invalidate();
                coverAlbum.setImageBitmap(null);
                if (cover != null){
                    coverAlbum.setImageBitmap(cover);
                }else {
                    coverAlbum.setBackgroundResource(R.drawable.mksong);
                }
            }
        }

        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, album)
    }
}
return v;

Upvotes: 1

ingyesid
ingyesid

Reputation: 2884

i am use Android Universal Loader ,for my the best library for made this https://github.com/nostra13/Android-Universal-Image-Loader

Upvotes: 1

Related Questions