yt-android-player icon indicating copy to clipboard operation
yt-android-player copied to clipboard

VideoListDemoActivity - Immediate notifyDataSetChanged

Open jmgirven opened this issue 10 years ago • 8 comments

I have included a slight variation of the example code from VideoListDemoActivity in my app. In my case, VideoListFragment is initialised with some cached content, and simultaneously a request is made to update to the latest set of videos. This can come back relatively quickly, whilst the cached video thumbnails are still in some form of loading state (Usually "1) The view has not yet been created"). When the new data is returned, I call notifyDataSetChanged on the adapter. Sometimes this will cause an IllegalStateException:

java.lang.IllegalStateException: Not connected. Call connect() and wait for onConnected() to be called.
        at com.google.android.youtube.player.a.at.i(Unknown Source)
        at com.google.android.youtube.player.a.an.k(Unknown Source)
        at com.google.android.youtube.player.a.an.a(Unknown Source)
        at com.google.android.youtube.player.a.ao.<init>(Unknown Source)
        at com.google.android.youtube.player.a.f.a(Unknown Source)
        at com.google.android.youtube.player.s.a(Unknown Source)
        at com.google.android.youtube.player.a.at.g(Unknown Source)
        at com.google.android.youtube.player.a.ax.a(Unknown Source)
        at com.google.android.youtube.player.a.aw.a(Unknown Source)
        at com.google.android.youtube.player.a.av.handleMessage(Unknown Source)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5171)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:837)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:653)

I have managed to reproduce this consistently in my version. If I stop the notifyDataSetChanged, or even delay it by 0.5 seconds, there is no crash. Can you reproduce this too? Any suggestions what I should do in this case?

Thanks, Jon.

jmgirven avatar Oct 09 '14 15:10 jmgirven

My initial diagnosis of notifyDataSetChanged being called too soon was close. I had introduced a check to see if a view was being reused in the list for a different thumbnail. This occasionally led me to call "thumbnail.initialize" on a view that was being initialised. I believe this is where the error originates from. Avoiding this check has stopped the crash.

jmgirven avatar Oct 13 '14 16:10 jmgirven

Thanks this helped me a lot, introducing a simple check solved my issues

fanky10 avatar May 02 '16 15:05 fanky10

Could anyone please post a sample code for the fix or elaborate on it. Sadly, this discussion leads me nowhere. Thanks.

parasjain1 avatar Dec 06 '17 18:12 parasjain1

https://stackoverflow.com/questions/35289106/java-lang-illegalstateexception-not-connected-call-connect-and-wait-for-onco/47693216#47693216

I have the same problem "YouTubeThumbnailView Not connected. Call connect() and wait for onConnected() to be called" in RecyclerView.Adapter by scrolling quickly and there are 3 youtube thumbnails in the recylerView.

In the adapter I put like this: a field: private boolean readyForLoadingYoutubeThumbnail = true; and at onBindViewHolder

/**
 * https://issuetracker.google.com/issues/35176819#c6
 * https://github.com/youtube/yt-android-player/issues/2#issuecomment-58913900
 * YouTubeThumbnailView Not connected. Call connect() and wait for onConnected() to be called
 */
Log.d(TAG, "readyForLoadingYoutubeThumbnail" + readyForLoadingYoutubeThumbnail);
final YouTubeInitializationResult result = YouTubeApiServiceUtil.isYouTubeApiServiceAvailable(activity);
if (readyForLoadingYoutubeThumbnail) {
    Log.d(TAG, "initializing for youtube thumbnail view...");
    readyForLoadingYoutubeThumbnail = false;
    holder.youTubeThumbnailView.initialize("aaaaaaaaaa", new YouTubeThumbnailView.OnInitializedListener() {
        @Override
        public void onInitializationSuccess(final YouTubeThumbnailView youTubeThumbnailView, final YouTubeThumbnailLoader youTubeThumbnailLoader) {

            youTubeThumbnailLoader.setVideo(videoId);
            youTubeThumbnailLoader.setOnThumbnailLoadedListener(new YouTubeThumbnailLoader.OnThumbnailLoadedListener(){

                @Override
                public void onThumbnailLoaded(YouTubeThumbnailView childYouTubeThumbnailView, String s) {
                    childYouTubeThumbnailView.setVisibility(View.VISIBLE);
                    holder.relativeLayoutOverYouTubeThumbnailView.setVisibility(View.VISIBLE);
                    youTubeThumbnailLoader.release(); // spy ga memory lick
                }

                @Override
                public void onThumbnailError(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader.ErrorReason errorReason) {
                    youTubeThumbnailLoader.release(); // spy ga memory lick
                }
            });
            youTubeThumbnailView.setColorFilter(Color.rgb(123, 123, 123), android.graphics.PorterDuff.Mode.MULTIPLY);

            readyForLoadingYoutubeThumbnail = true;
        }

        @Override
        public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) {
            //do nohing.. ada error, tambahin method ini jalan, error-nya lupa...
            readyForLoadingYoutubeThumbnail = true;
        }
    });
}

It is works for me...

rudiw avatar Dec 07 '17 10:12 rudiw

@parasjain1 ... i agreed with you...

Sadly, this discussion leads me nowhere

rudiw avatar Dec 08 '17 02:12 rudiw

@rudiw wow great solution it worked for me !!

raedsaeed avatar Mar 16 '18 06:03 raedsaeed

When I use this solution, the initialize method is called for particular positions only. For example, I have three items per page, when I load that in the recycler view, the initialize method is called only for the 0 position. After pagination, another 3 items received, in that the initialize method is called only for 4 and 5 positions. The initialize method is not called for 1,2 and 3 positions. So, please suggest a solution that works in this scenario.

madhankumardroid avatar Mar 30 '18 12:03 madhankumardroid

https://stackoverflow.com/questions/35289106/java-lang-illegalstateexception-not-connected-call-connect-and-wait-for-onco/47693216#47693216

I have the same problem "YouTubeThumbnailView Not connected. Call connect() and wait for onConnected() to be called" in RecyclerView.Adapter by scrolling quickly and there are 3 youtube thumbnails in the recylerView.

In the adapter I put like this: a field: private boolean readyForLoadingYoutubeThumbnail = true; and at onBindViewHolder

/**
 * https://issuetracker.google.com/issues/35176819#c6
 * https://github.com/youtube/yt-android-player/issues/2#issuecomment-58913900
 * YouTubeThumbnailView Not connected. Call connect() and wait for onConnected() to be called
 */
Log.d(TAG, "readyForLoadingYoutubeThumbnail" + readyForLoadingYoutubeThumbnail);
final YouTubeInitializationResult result = YouTubeApiServiceUtil.isYouTubeApiServiceAvailable(activity);
if (readyForLoadingYoutubeThumbnail) {
    Log.d(TAG, "initializing for youtube thumbnail view...");
    readyForLoadingYoutubeThumbnail = false;
    holder.youTubeThumbnailView.initialize("aaaaaaaaaa", new YouTubeThumbnailView.OnInitializedListener() {
        @Override
        public void onInitializationSuccess(final YouTubeThumbnailView youTubeThumbnailView, final YouTubeThumbnailLoader youTubeThumbnailLoader) {

            youTubeThumbnailLoader.setVideo(videoId);
            youTubeThumbnailLoader.setOnThumbnailLoadedListener(new YouTubeThumbnailLoader.OnThumbnailLoadedListener(){

                @Override
                public void onThumbnailLoaded(YouTubeThumbnailView childYouTubeThumbnailView, String s) {
                    childYouTubeThumbnailView.setVisibility(View.VISIBLE);
                    holder.relativeLayoutOverYouTubeThumbnailView.setVisibility(View.VISIBLE);
                    youTubeThumbnailLoader.release(); // spy ga memory lick
                }

                @Override
                public void onThumbnailError(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader.ErrorReason errorReason) {
                    youTubeThumbnailLoader.release(); // spy ga memory lick
                }
            });
            youTubeThumbnailView.setColorFilter(Color.rgb(123, 123, 123), android.graphics.PorterDuff.Mode.MULTIPLY);

            readyForLoadingYoutubeThumbnail = true;
        }

        @Override
        public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) {
            //do nohing.. ada error, tambahin method ini jalan, error-nya lupa...
            readyForLoadingYoutubeThumbnail = true;
        }
    });
}

It is works for me...

Perhaps private boolean readyForLoadingYoutubeThumbnail = true; should be added in Viewholder not in adapter. This way next ViewHolder thumbnail initialization won't stop until last viewholder has been initialized.

bharatsingh2 avatar Aug 07 '19 08:08 bharatsingh2