How to load Youtube thumbnails in a RecyclerView using Youtube API

Stranger B. picture Stranger B. · Dec 19, 2015 · Viewed 17.6k times · Source

I'm trying to load Youtube video thumbnails in a RecyclerView. I'm facing some issues.

Here is what I'm doing in my adapter:

public static class ItemViewHolder extends RecyclerView.ViewHolder {

    private YouTubeThumbnailView thumb;
    public  Post                 post;

    public ItemViewHolder(View v) {
        thumb = (YouTubeThumbnailView) v.findViewById(R.id.youtube_thumbnail);
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
        if (holder instanceof ItemViewHolder) {

            ((ItemViewHolder) holder).thumb.initialize(YOUTUPEKEY, new YouTubeThumbnailView.OnInitializedListener() {
                @Override
                public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader youTubeThumbnailLoader) {
                    youTubeThumbnailLoader.setVideo(VIDEOID);

                }

                @Override
                public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) {

                }});
}}}

It works fine, but I don't I'm doing it right. When I'm using the same adapter in another activity I get this Error:

Activity com.example.yasser.version6.Mespublications has leaked ServiceConnection com.google.android.youtube.player.internal.r$e@4252bcb8 that was originally bound here

and it takes time to load thumbnails and sometimes it mix between them when swiping.

I added a function to release all the Youtube Loaders:

public void ReleaseLoaders() {
    for (YouTubeThumbnailLoader loader : loaders.values()) {
        loader.release();
    }
}

and I'm calling this function from the Activity Onstop() :

@Override
public void onStop() {
    super.onStop();
    mAdapter.ReleaseLoaders();
}

It worked fine for some time, but the crashes sometimes.

Answer

Arnold Balliu picture Arnold Balliu · Dec 30, 2015

You can try this maybe ? It doesnt use the API but its quick.

Load the image in the recycler view with Picasso from this URL:

https://img.youtube.com/vi/"here goes your video id"/default.jpg

-- Edit --

After some research and experiments:

To get the default full size thumbnail do this instead of default.jpg

https://img.youtube.com/vi/"here goes your video id"/0.jpg

Here is the link: http://www.reelseo.com/youtube-thumbnail-image/

Edit 2:

Just found someone in SO already gave an answer like mine with this quick and easy solution and has way more explanation and options you could choose from.

How do I get a YouTube video thumbnail from the YouTube API?


Final Edit:

This is working code. I went in and made an app recently with the api so I found out why you are getting the error. Its because you are not releasing the loader properly.

You can release the loader/loaders in two ways.

First

(Preferred, you will see why in a sec) You would want to release it after the image has been loaded into view and theres a listener for that and its called OnThumbNailLoadedListener. Thats where I released it (if you pay attention to the code below). This means you dont have to deal with this instance anymore. Once thumbnail is loaded youre done.

Second

Since getView() is called all the time there's new instances of YouTubeThumbnailLoader that you have to release. This means you have to store all of these in an ArrayList. You just do an advanced for loop and call release in all of them when activity is onStop();

Now you probably see why the first way is preferred. And I know you did the second option so just letting you know the first option will always be guaranteed to work (at least in my case). I used a YouTubeSupportFragment in an Activity and it worked fine. No issues whatsoever. You can definitely make the second option work but you would have to handle a lot of special cases I think.

final YouTubeThumbnailView youTubeThumbnailView = (YouTubeThumbnailView) convertView.findViewById(R.id.show_episode_thumbnail);
    youTubeThumbnailView.initialize(DeveloperKey.DEVELOPER_KEY, new YouTubeThumbnailView.OnInitializedListener() {
        @Override
        public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, final YouTubeThumbnailLoader youTubeThumbnailLoader) {
            youTubeThumbnailLoader.setVideo(videoId);
            youTubeThumbnailLoader.setOnThumbnailLoadedListener(new YouTubeThumbnailLoader.OnThumbnailLoadedListener() {
                @Override
                public void onThumbnailLoaded(YouTubeThumbnailView youTubeThumbnailView, String s) {
                    youTubeThumbnailLoader.release();
                }

                @Override
                public void onThumbnailError(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader.ErrorReason errorReason) {

                }
            });
        }

        @Override
        public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) {

        }
    });