5

Today Android Studio (set to Stable channel updates) has offered me to download an update to Android Support Repository 46.0.0, so I did it. Then suddenly our app has started to crash each time because of MenuItemCompat.setOnActionExpandListener.

Yes I've should have check release notes yet, but I did not - that's a fact.

Now what's our problem - Even we're using recommended notation MenuItemCompat.setOnActionExpandListener, our app crashed and we're advised to to use MenuItemCompat.setOnActionExpandListener. That's nonsense.

Is there someone who run into the same issue or is it just a matter of our code? Can someone provide an advice how to fix this or how to force to use earlier version of support library? Let's say 25.1.0. Issue seems to be in 26.0.0-alpha1 which is very likely included in Support Repository version 46 (see Release notes for that repository - https://developer.android.com/topic/libraries/support-library/revisions.html#26-0-0-alpha1)

Btw. our build.gradle already states fix version for support libs to 25.1.0. It seems new support library somehow forces to use other versions internally when built with gradle.

   compile 'com.android.support:appcompat-v7:25.1.0'
   compile 'com.android.support:design:25.1.0'
   compile 'com.android.support:support-v4:25.1.0'

Thank you very much.

Code

MenuItemCompat.setOnActionExpandListener(menu.findItem(R.id.action_search), new MenuItemCompat.OnActionExpandListener() {
                @Override
                public boolean onMenuItemActionExpand(MenuItem menuItem) {
                    ...
                }

Part of StackTrace

    E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.dev, PID: 4835
java.lang.UnsupportedOperationException: This is not supported, use MenuItemCompat.setOnActionExpandListener()
at android.support.v7.view.menu.MenuItemImpl.setOnActionExpandListener(MenuItemImpl.java:745)
at android.support.v4.view.MenuItemCompat.setOnActionExpandListener(MenuItemCompat.java:363)
at com.example.fragments.DevicesFragment.onCreateOptionsMenu(DevicesFragment.java:455)
at android.support.v4.app.Fragment.performCreateOptionsMenu(Fragment.java:2338)
at android.support.v4.app.FragmentManagerImpl.dispatchCreateOptionsMenu(FragmentManager.java:3070)
at android.support.v4.app.FragmentController.dispatchCreateOptionsMenu(FragmentController.java:328)
at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:321)
at android.support.v7.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:95)
at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.onCreatePanelMenu(AppCompatDelegateImplBase.java:333)
at android.support.v7.app.AppCompatDelegateImplV9.preparePanel(AppCompatDelegateImplV9.java:1372)
at android.support.v7.app.AppCompatDelegateImplV9.doInvalidatePanelMenu(AppCompatDelegateImplV9.java:1652)
at android.support.v7.app.AppCompatDelegateImplV9$1.run(AppCompatDelegateImplV9.java:134)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)

UPDATE: This seems to be connected to this issue, since I've tried that also and same thing happened to me. I do not want to update to API 26 anyway - Android Support Repo 46.0.0 with Android Studio 2.3

Community
  • 1
  • 1
  • Gradle dependency resolution is sadly ignoring "25.1.0" in favor of e.g. "[25.0.0,)" from transitive dependencies and takes whatever is the newest. See http://stackoverflow.com/a/42957234/2444099 – Eugen Pechanec Mar 22 '17 at 20:52
  • Thank you @Eugen. I've found it yesterday too and it makes sense. Anyway, since I can't rely on how I've set up my libs is respected by gradle I've decided to cleanup my SDK installation and instead of praying or hoping it will do what I suppose I did a rollback to ASR 45.0.0 - gladly my second machine was not updated, so I've just copies {sdkpath}/android/extras to my updated one and it rolled back to 45. What I don't understand is why AS offered me an incompatible update. This leads me to a conclusion that Google is not able to guarantee stability for production development. And that's sad. – T. Tiscalli Mar 23 '17 at 09:05
  • Rolling back doesn't help. Say you wanted 25.1.0 but the latest in repo 45 is 25.3.0. Same problem: different versions of different support libs are used. Only because the manifest meta-data was introduced in 25.3.0 you don't see the conflict. Run `gradlew dependencies --configuration compile -p ` to verify. Gradle works very much according to docs. One of your dependencies is making you always pull some of the latest support libs no matter what. The only reliable way is to force the version. And you want the same version across support libs anyway. Win-win. – Eugen Pechanec Mar 23 '17 at 09:20
  • Hello @Eugen - yes, you're totally right! It is much more clearer now and you saved me from headache in future. Thank you. – T. Tiscalli Mar 23 '17 at 13:25
  • No problem, good luck! – Eugen Pechanec Mar 23 '17 at 13:35

2 Answers2

3

It is just a bug in the 26.0.0-alpha1 release. Switch back to 25.3.0 by updating your build.gradle file.

ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
  • Hello @ianhanniballake, thank you for an answer. This is where it's weird, since our build.gradle have set that to a fix version 25.1.0 - **we're not** using dynamic versions (e.g. 25+) – T. Tiscalli Mar 22 '17 at 20:27
  • @T.Tiscalli - what does `gradlew androidDependencies` say? That should tell you who is upgrading you to 26.0.0 – ianhanniballake Mar 22 '17 at 21:09
  • Hello @ianhanniballake - I've rolled back to Android Support Repository 45.0.0 so I can't say for sure now. Anyway when I try this right now and even I've set support libs to 25.1.0 I've getting 25.3.0 anyway. What a shame Google does not respect developer's decision. – T. Tiscalli Mar 23 '17 at 09:09
  • @T.Tiscalli This has nothing to do with Google. It's Gradle dependency resolution in action. One of the libraries you use declared dependency on e.g. "support libs 25.0.0 or newer". If it declared "support libs 25.0.0" instead everything would work as expected (Gradle would pull the newest specified). This is not Google's fault, not Gradle's fault, stop being so short sighted and assigning blame instead of investigating like a proper engineer. – Eugen Pechanec Mar 23 '17 at 09:28
  • There's a reason Gradle let's you exclude transitive dependencies: it is exactly the tool you need to work around overzealous dependencies. – ianhanniballake Mar 23 '17 at 11:39
  • @Eugen - thanks for your comments but I prefer discussion instead of being impolite and try to harm other people - ok, your choice, hope you're far more happier now. I personally rather admit I'm wrong than to not say something because I'm scared of talking to no harm any other's feeling. – T. Tiscalli Mar 23 '17 at 12:35
  • Gradle is just doing exactly what you asked it to do. You are completely in control of what dependencies your app brings in and what transitive dependency rules you allow. – ianhanniballake Mar 23 '17 at 12:39
  • Thanks @ianhanniballake. I had no idea about transitive dependencies. My assumptions and knowledge were then wrong, anyway I can work only with the amount of knowledge I have or I can gather. My note was meant that I don't understand why if I explicitly define 25.1.0 I still got some else. I would expect at least receiving an exception or maybe warning. App has not been tested with other versions and I've been thinking this behavior is a bug. There's always something new to learn. – T. Tiscalli Mar 23 '17 at 12:48
  • Btw. need to apologize for my premature assumption regarding Google. Just in my defense - it was based on conviction that such a thing needs to be respected - my amount of knowledge was the issue. – T. Tiscalli Mar 23 '17 at 13:42
-1

UPDATE 23.3.2017: Based on comments and further research the right way is really to force gradle to use explicit version when Gradle dependency resolution makes you to use any other version than desired.

Thanks to @Eugen and @ianhanniballake you can use following steps to decide if any action is needed and force the explicit version.

  1. Run gradlew androidDependencies to check which versions are resolved and used by Gradle
  2. If it does not match your required explicit version, force it as stated by @Eugen on this topic - https://stackoverflow.com/a/42957234/816216 (snippet posted below)

_

configurations.all {
    resolutionStrategy.eachDependency { DependencyResolveDetails details ->
        def requested = details.requested
        if (requested.group == 'com.android.support') {
            if (!requested.name.startsWith("multidex")) {
                details.useVersion '25.3.0'
            }
        }
    }
}
Community
  • 1
  • 1
  • Not good enough if you can't/won't use support libs 25.3.0. Will break if a version > 25.3.0 is released in new repo version. There's an accepted working solution for the question you referenced so *"there's no way how to fix this issue"* is false. – Eugen Pechanec Mar 23 '17 at 09:24
  • Guys, rolling back to Android Support Repository 45.0.0 will do help when you want to solve the issue of getting rid of Support Library 26.0.0-alpha! And that was the topic of my question. I can't get why this is marked as -1. – T. Tiscalli Mar 23 '17 at 12:27
  • 1
    Because it is the wrong solution. The solution is to fix your Gradle dependencies – ianhanniballake Mar 23 '17 at 12:37
  • Okay, I see it now - https://docs.gradle.org/current/userguide/dependency_management.html#sec:dependency_resolution – T. Tiscalli Mar 23 '17 at 13:04
  • Answer changed based on comments – T. Tiscalli Mar 23 '17 at 13:21