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

App crashes with unhelpful error if `autoplay=true` but no `videoId` is provided

Open PierfrancescoSoffritti opened this issue 5 years ago • 8 comments

This is not a valid configuration, since autoPlay is true, but no videoId is provided.

<com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
        android:id="@+id/youtube_player_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:autoPlay="true" />

The app crashes with an unhelpful error.

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.shuffly/com.shuffly.ui.MainActivity}: android.view.InflateException: Binary XML file line #18 in com.shuffly:layout/activity_main: Binary XML file line #18 in com.shuffly:layout/activity_main: Error inflating class com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView

We should improve the UX by not crashing or at least providing an useful error.

PierfrancescoSoffritti avatar Apr 01 '20 20:04 PierfrancescoSoffritti

Hi,

What branch is this occurring on?

I tested both dev and master they both show a proper error message. This is from the dev branch, notice the IllegalStateException that's located somewhere in the middle:

    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.pierfrancescosoffritti.aytplayersample/com.pierfrancescosoffritti.androidyoutubeplayer.core.sampleapp.examples.completeExample.CompleteExampleActivity}: android.view.InflateException: Binary XML file line #9: Binary XML file line #9: Error inflating class com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2684)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2751)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1496)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6186)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
     Caused by: android.view.InflateException: Binary XML file line #9: Binary XML file line #9: Error inflating class com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
     Caused by: android.view.InflateException: Binary XML file line #9: Error inflating class com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
        at android.view.LayoutInflater.createView(LayoutInflater.java:645)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:787)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:377)
        at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:555)
        at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:161)
        at com.pierfrancescosoffritti.androidyoutubeplayer.core.sampleapp.examples.completeExample.CompleteExampleActivity.onCreate(CompleteExampleActivity.java:43)
        at android.app.Activity.performCreate(Activity.java:6684)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2637)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2751)
        at android.app.ActivityThread.-wrap12(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1496)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6186)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
     Caused by: java.lang.IllegalStateException: YouTubePlayerView: videoId is not set but autoPlay is set to true. This combination is not possible.
        at com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView.<init>(YouTubePlayerView.kt:62)
        at com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView.<init>(YouTubePlayerView.kt:28)
        at java.lang.reflect.Constructor.newInstance0(Native Method) 
        at java.lang.reflect.Constructor.newInstance(Constructor.java:430) 
        at android.view.LayoutInflater.createView(LayoutInflater.java:645) 
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:787) 
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727) 
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:858) 
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:518) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:426) 
        at android.view.LayoutInflater.inflate(LayoutInflater.java:377) 
        at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:555) 
        at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:161) 
        at com.pierfrancescosoffritti.androidyoutubeplayer.core.sampleapp.examples.completeExample.CompleteExampleActivity.onCreate(CompleteExampleActivity.java:43) 
        at android.app.Activity.performCreate(Activity.java:6684) 
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2637) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2751) 
        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1496) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.app.ActivityThread.main(ActivityThread.java:6186) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779) 

AbelTesfaye avatar Apr 02 '20 08:04 AbelTesfaye

I can confirm AbelTesfaye's statement. The error message "videoId is not set but autoPlay is set to true. This combination is not possible." occurs and is understandable.

The question is, should the app crash when an invalid configuration is provided or should it hide some UI elements and only log the error (like in #639)?

malliaridis avatar Oct 03 '20 15:10 malliaridis

@malliaridis,

I think we don't need the throw an exception. It could be a Log.w or Log.e because if videoId is missing YoutubePlayerView just shows progressBar like loading video and when the loadVideo called it continues default steps.

Because default youTubePlayerListener uses videoId with let

videoId?.let {
       youTubePlayer.loadOrCueVideo(legacyTubePlayerView.canPlay && autoPlay, videoId, 0f)
}

And also showing a missing videoId icon/text is unnecessary.

furkanaskin avatar Oct 03 '20 19:10 furkanaskin

Ideally I prefer throwing the exception, since the combination is not valid. If I remember correctly, when videoId is missing (without adding custom UI for the "no video id" state) it's not clear why the player is not working.

My issue with the current implementation is that the stack trace is not very readable. The exception message is lost between lines of useless stuff. Which is not the best user experience.

I am not sure how to improve this, since as far as I know, exceptions thrown while inflating a layout are always shown like that. Maybe we can throw after inflation is completed?

PierfrancescoSoffritti avatar Oct 04 '20 06:10 PierfrancescoSoffritti

To be honest, I already got used to those kind of error messages (with the boilerplate lines). I am looking always for the line that is not indented and starts with "Caused by...". Therefore, finding the error is not much of a problem.

Throwing an exception is maybe a way to go, but this prevents I think an implementation of 2-way data binding, which was my first attempt implementing the player library. I failed due to this exception, because my video id wasn't ready on initialization.

Therefore, I think throwing the exception is not a long term option.

malliaridis avatar Oct 04 '20 12:10 malliaridis

this prevents I think an implementation of 2-way data binding

good point, didn't think of that.

PierfrancescoSoffritti avatar Oct 05 '20 13:10 PierfrancescoSoffritti

<com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView
        android:id="@+id/youtube_player_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:autoPlay="true" />

How can I set this youtube player video id on programmatically

mBinding.youtubePlayerView.addYouTubePlayerListener(object: AbstractYouTubePlayerListener() {
            override fun onReady(youTubePlayer: YouTubePlayer) {
               // val videoId = "S0Q4gqBUs7c"
                val videoId = getYouTubeVideoIdFromUrl(URL)
                if (videoId != null) {
                    youTubePlayer.loadVideo(videoId, 0f)
                }
                youTubePlayer.removeListener(this)

            }
        })  

without this listener I am already set but I want to video id set with any different method access with youtubeplayer object or youtubeplayerview method any one can help me I am stuck for while I am not able to find which method set to video id

here I am using com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView this libarry

    implementation 'com.pierfrancescosoffritti.androidyoutubeplayer:core:12.0.0'

@GauravMeghanathiWeDoApps I don't understand what you're asking, could you clarify? also your issue doesn't seem related to this issue, could you open a new one instead?

PierfrancescoSoffritti avatar Aug 04 '23 08:08 PierfrancescoSoffritti