Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default interface methods are only supported starting with Android N #5276

Closed
ArcherEmiya05 opened this issue Dec 18, 2018 · 29 comments
Closed

Comments

@ArcherEmiya05
Copy link

ExoPlayer version:
implementation 'com.google.android.exoplayer:exoplayer:2.9.2'

Issue:
While rebuilding the app I encountered so many deprecated code as expected so I refactor it but now I am getting this new error:
Error: Default interface methods are only supported starting with Android N (--min-api 24): void com.google.android.exoplayer2.Player$EventListener.onSeekProcessed().

Codes Before:

private final Player.EventListener eventListener = new Player.DefaultEventListener(){
@OverRide
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState){
//Buffer after doing forward,backward, or seek
case Player.STATE_BUFFERING:
break;
//Ready when it starts playing or start/stop is clicked
case Player.STATE_READY:
break;
//Idle after calling error or still no internet connection after doing forward,backward, or seek
case Player.STATE_IDLE:
//Save the last seek position
saveLastPosition();
createPlayers();
break;
//Ended if the streaming is finish
case Player.STATE_ENDED:
playerView.showController();
break;
}

//Since isRepeating is only true in RecyclerView this will not be triggered unless Player is hosted by Activity
if (!isRepeating)
EventBus.getDefault().post(new UpdateOption(itemPosition));
}

Then it says @deprecated Use {@link EventListener} interface directly for selective overrides as all methods are implemented as no-op default methods. so I update it to this

private final Player.EventListener eventListener = new Player.EventListener(){
@OverRide
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState){
//Buffer after doing forward,backward, or seek
case Player.STATE_BUFFERING:
break;
//Ready when it starts playing or start/stop is clicked
case Player.STATE_READY:
break;
//Idle after calling error or still no internet connection after doing forward,backward, or seek
case Player.STATE_IDLE:
//Save the last seek position
saveLastPosition();
createPlayers();
break;
//Ended if the streaming is finish
case Player.STATE_ENDED:
playerView.showController();
break;
}

//Since isRepeating is only true in RecyclerView this will not be triggered unless Player is hosted by Activity
if (!isRepeating)
EventBus.getDefault().post(new UpdateOption(itemPosition));
}

@OverRide
public void onPositionDiscontinuity(int reason) {
if (player.getPlaybackError() != null) {
//The user has performed a seek whilst in the error state. Update the resume position so
//that if the user then retries, playback resumes from the position to which they seek.
position = Math.max(0, player.getContentPosition());
}
}

};

@ojw28 ojw28 self-assigned this Dec 18, 2018
@ojw28 ojw28 added the question label Dec 18, 2018
@ojw28
Copy link
Contributor

ojw28 commented Dec 18, 2018

You need to add

compileOptions {
    targetCompatibility JavaVersion.VERSION_1_8
}

to your build.gradle files, as described in the developer guide. You can refer to the ExoPlayer demo app for an example (and also confirm that it compiles fine, despite having minSdkVersion 16.

@ojw28 ojw28 closed this as completed Dec 18, 2018
@AndroidDeveloperLB
Copy link

AndroidDeveloperLB commented Jan 7, 2019

@ojw28 This didn't work for me. I've even tested on the Canary build of the IDE, and on a sample project that doesn't even use ExoPlayer, and it doesn't even work if the minSdk is 24 . See here:

https://youtrack.jetbrains.com/issue/KT-29138

In my case, I wanted to use this:

 player!!.addListener(object : Player.EventListener {
                    override fun onPositionDiscontinuity(reason: Int) {
                        super.onPositionDiscontinuity(reason)
                        Log.d("AppLog", "onPositionDiscontinuity: reason : $reason currentWindowIndex: ${player?.currentWindowIndex}")
                    }
                })

But I still got this error.
Please fix this issue.

@tonihei
Copy link
Collaborator

tonihei commented Jan 7, 2019

I needed to set the Kotlin JVM version in the Android Studio settings to get that to work.
File -> Settings -> Other Settings -> Kotlin Compiler -> Target JVM version. The default in my Android Studio is 1.6. but should be 1.8.

@AndroidDeveloperLB
Copy link

AndroidDeveloperLB commented Jan 7, 2019

@tonihei Then it's not enabled by default, doesn't tell to change it, and doesn't offer this fix.

Also, after changing it, it didn't help. I tried to re-build the project. Didn't help. Still got the error.
Restarting the IDE also didn't help.

On the sample project, it only seemed to be fine as it doesn't mark the error on the textual editor of the Kotlin file, but on the large one it showed it. However, when trying to launch the sample, it failed with this error. How could it be?

Here's how it looks on the sample project:

image

Attached a sample project, where it works fine, and a screenshot of the large one...

image

ExoPlayerTest.zip

@tonihei
Copy link
Collaborator

tonihei commented Jan 7, 2019

Unfortunately, we can't help you debug your app. Given that it works fine in a small example suggests that it works in principle and something else in your larger project is misconfigured. This kind of question is better posted in StackOverflow or similar sites.

We'll update our docs to note how the configuration for Kotlin looks like.

@tonihei tonihei reopened this Jan 7, 2019
@tonihei tonihei self-assigned this Jan 7, 2019
@AndroidDeveloperLB
Copy link

AndroidDeveloperLB commented Jan 7, 2019

@tonihei It only visually works on the ExoPlayer sample I've made (doesn't mark the line with an error). When trying to build&run, it gave an error. Please check the updated post.

So it doesn't matter if it's on the large project or the sample. On both it didn't work.

Please explain what I should do.

@tonihei
Copy link
Collaborator

tonihei commented Jan 7, 2019

On the sample project, it seemed to fine as it doesn't mark the error, but on the large one it showed it.

Doesn't that say that it works on the sample project?

@AndroidDeveloperLB
Copy link

No. Look at the screenshot. It clearly shows that I can't build&run the project because of it. It just doesn't mark the line.

Only when I remove the call to "super...", it works perfectly fine, both visually and when trying to build&run.

@AndroidDeveloperLB
Copy link

AndroidDeveloperLB commented Jan 7, 2019

Here, I've made a video for you to understand:

2019-01-07_12-40-52.zip

Please talk to the Kotlin or Android-Studio guys (or IntelliJ). It's a problem that will exist not just for ExoPlayer...

@tonihei
Copy link
Collaborator

tonihei commented Jan 7, 2019

It works perfectly fine for a fresh Kotlin project using ExoPlayer and the listener call as in your example in Android Studio 3.2.1. I'd suggest copying parts of your code to a new project to see at which point it goes wrong.

@tonihei
Copy link
Collaborator

tonihei commented Jan 7, 2019

Aside: There is no point in calling super for a default interface implementation because these are not meant to be called anyway and are only there for interface implementations which don't override the methods themselves. As soon as you provide your own implementation for a method, you shouldn't call into the default interface implementation.

@AndroidDeveloperLB
Copy link

AndroidDeveloperLB commented Jan 7, 2019

So the IDE auto-completes the call to "super" for the wrong reason?
When you say "these are not meant to be called", does it mean they can't be called in general, or just on this specific case of ExoPlayer?
In general, is the default implementation (on Kotlin and Java) available only in case you don't override them? It won't run in case you override them?

Also, what exactly works? With, or without the call to the "super" ? Can you please share a sample project with this listener?

@tonihei
Copy link
Collaborator

tonihei commented Jan 7, 2019

When you say "these are not meant to be called", does it mean they can't be called in general, or just on this specific case of ExoPlayer?

That depends on how you use them. A common interpretation is to use them as a fallback if no other implementation is provided and you therefore shouldn't call them directly from a subclass (that's what we do in ExoPlayer). But of course the language allows to call them and it's unclear how the IDE should implement that correctly.

@AndroidDeveloperLB
Copy link

AndroidDeveloperLB commented Jan 7, 2019

So the IDE is fine when it suggests it, then, just like in similar cases. In general, the default implementation should be called in some cases, which might not always be clear for people who use the interface.

But why does it show an error ? Can you please share me your sample project? I want to know what causes it, and if your sample project would produce the same issue.

Is it ok on ExoPlayer, at least, not to ever call "super" here? I think the Listener doesn't need a default implementation anyway. It's just a nice replacement to a normal interface, so that we won't have to create multiple empty implementations, one for each function...

@tonihei
Copy link
Collaborator

tonihei commented Jan 7, 2019

Is it ok on ExoPlayer, at least, not to ever call "super" here?

Yes, it is. The default implementations are all empty anyway.

@AndroidDeveloperLB
Copy link

Yes I know, but technically they might still not be empty in the future. I mean to ask if it will always be this way.

@tonihei
Copy link
Collaborator

tonihei commented Jan 7, 2019

Yes, pretty sure. And even if not, we will never oblige an implementation to call the default super method in an interface.

@AndroidDeveloperLB
Copy link

I see. Can you please send me a sample nevertheless? One that does call "super" and yet builds&runs fine for you?

@tonihei
Copy link
Collaborator

tonihei commented Jan 7, 2019

That's my project. More or less the auto-generated example project with ExoPlayer dependency.
public_exoplayer.zip

@AndroidDeveloperLB
Copy link

AndroidDeveloperLB commented Jan 7, 2019

I can see you've added this, which wasn't added automatically by any of the settings screens of the IDE:

    kotlinOptions {
        jvmTarget = JavaVersion.VERSION_1_8
    }

Adding it fixed the issue completely. Please tell whoever's in charge about this.

@tonihei
Copy link
Collaborator

tonihei commented Jan 7, 2019

That's the equivalent of the Settings option in gradle. Both worked for me.

@AndroidDeveloperLB
Copy link

I don't know. Nothing on the IDE has added it so far, and I'm using the Canary build of it. I had to add it manually.

Maybe you've created a new project and it added it for you. On the current projects, it doesn't do it. Not even on the sample project that I've sent you, which isn't that old.

@AndroidDeveloperLB
Copy link

Say, is there a way in Kotlin/Java, to mark an interface easily that all of its functions are set to be "default" with empty implementation?
Currently I think that on Java you have to add "default" for each function and "{}" , and on Kotlin you have to add only "{}". But for both you have to do it for each function.

I've requested something similar in the past, here:

https://youtrack.jetbrains.com/issue/KT-22827

ojw28 pushed a commit that referenced this issue Jan 14, 2019
Setting the target conpatibility only seems to work for Java. Added the
equivalent Kotlin config options to the docs.

Issue:#5276
PiperOrigin-RevId: 228482496
ojw28 pushed a commit that referenced this issue Jan 15, 2019
Setting the target conpatibility only seems to work for Java. Added the
equivalent Kotlin config options to the docs.

Issue:#5276
PiperOrigin-RevId: 228482496
@zishanj
Copy link

zishanj commented Jan 15, 2019

I am also facing this issue in my Android Java app even I have added targetCompatibility JavaVersion.VERSION_1_8

@tonihei
Copy link
Collaborator

tonihei commented Jan 15, 2019

See commit above for how to configure Kotlin to use Java 8 features.

Closing this issue now as the doc has been updated.

@tonihei tonihei closed this as completed Jan 15, 2019
@zishanj
Copy link

zishanj commented Jan 15, 2019

@tonihei as I have mentioned, my issue is Java related not Kotlin.

@zishanj
Copy link

zishanj commented Jan 15, 2019

I have added these both lines in my Java app as mentioned in doc:

sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8

but its still throwing this error.

@ALi-Moslehi
Copy link

hi, i added


    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

but not work.

Error: Static interface methods are only supported starting with Android N (--min-api 24):

java.lang.Object com.google.android.exoplayer2.analytics.AnalyticsListener.access$super(com.google.android.exoplayer2.analytics.AnalyticsListener, java.lang.String, java.lang.Object[])

@AndroidDeveloperLB
Copy link

@ALi-Moslehi Try as such instead:

compileOptions {
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
}

@google google locked and limited conversation to collaborators May 16, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants