Fixed
Status Update
Comments
ki...@google.com <ki...@google.com> #2
Hi Ed, Thank you so much for these suggestions. I've been reviewing them and merging them in. Hopefully it should be live. I've included a thank you note too in the article.
ap...@google.com <ap...@google.com> #3
Great! Thanks a lot, I'll look for the live updates soon!
il...@google.com <il...@google.com> #4
We've updated AppCompat to no longer pass a null Menu. This will be available in a future 1.2.0 release.
ap...@google.com <ap...@google.com> #5
Project: platform/frameworks/support
Branch: androidx-main
commit 10990f668a04e5eb532cd173f44562d80eae06e2
Author: Jeremy Woods <jbwoods@google.com>
Date: Wed Jun 22 16:26:37 2022
Restrict devices for ComponentActivity menu tests
Prior to SDK 26, it was possible to pass null menus to Activity menu
APIs. b/142843126 added nullability annotations to framework Activity
that ensured that any menu passed to the menu APIs were non-null.
LeakCanary was implemented in Kotlin with the expectations that the new
framework Activity nullability contracts would hold true. In reality
that is not the case, and on API levels 25 and lower, you can get a
non-null menu passed to a framework API.
There is nothing we can do to address this in the framework. The only
way to run into this issue is by using ActionBar with ComponentActivity
and attempting to use a null menu. Any devs interacting with ActionBar
should be using AppCompantActivity which addresses this issue.
Otherwise, they should be using ToolBar, which also addresses this.
We are going to move these particular test to only run on API 26 and
above to avoid these failures.
Test: updated tests
Fixes: 236868265
Fixes: 229013665
Change-Id: Ib4f606d4a1533bf9b56bd3346c0b5772d5e3cf47
M activity/activity/src/androidTest/java/androidx/activity/ComponentActivityMenuTest.kt
https://android-review.googlesource.com/2134516
Branch: androidx-main
commit 10990f668a04e5eb532cd173f44562d80eae06e2
Author: Jeremy Woods <jbwoods@google.com>
Date: Wed Jun 22 16:26:37 2022
Restrict devices for ComponentActivity menu tests
Prior to SDK 26, it was possible to pass null menus to Activity menu
APIs.
that ensured that any menu passed to the menu APIs were non-null.
LeakCanary was implemented in Kotlin with the expectations that the new
framework Activity nullability contracts would hold true. In reality
that is not the case, and on API levels 25 and lower, you can get a
non-null menu passed to a framework API.
There is nothing we can do to address this in the framework. The only
way to run into this issue is by using ActionBar with ComponentActivity
and attempting to use a null menu. Any devs interacting with ActionBar
should be using AppCompantActivity which addresses this issue.
Otherwise, they should be using ToolBar, which also addresses this.
We are going to move these particular test to only run on API 26 and
above to avoid these failures.
Test: updated tests
Fixes: 236868265
Fixes: 229013665
Change-Id: Ib4f606d4a1533bf9b56bd3346c0b5772d5e3cf47
M activity/activity/src/androidTest/java/androidx/activity/ComponentActivityMenuTest.kt
Description
1. Add a menu to the activity
2. Override the onMenuOpened callback
3. Tap the overflow menu
Notice that callback was invoked with the null menu, despite the signature having a NonNull annotation
Kotlin apps might get a crash if they treated the platform type as non-null or a type-mismatch warning if the menu argument is declared as nullable and super.onMenuOpened is invoked.
10-17 10:37:16.152 E/AndroidRuntime( 843): Process: some.package, PID: 843
10-17 10:37:16.152 E/AndroidRuntime( 843): java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter menu
10-17 10:37:16.152 E/AndroidRuntime( 843): at some.activity.onMenuOpened(Unknown Source:2)
10-17 10:37:16.152 E/AndroidRuntime( 843): at androidx.appcompat.view.WindowCallbackWrapper.onMenuOpened(WindowCallbackWrapper.java:104)
10-17 10:37:16.152 E/AndroidRuntime( 843): at androidx.appcompat.app.AppCompatDelegateImpl$AppCompatWindowCallback.onMenuOpened(AppCompatDelegateImpl.java:2868)
10-17 10:37:16.152 E/AndroidRuntime( 843): at androidx.appcompat.view.WindowCallbackWrapper.onMenuOpened(WindowCallbackWrapper.java:104)
10-17 10:37:16.152 E/AndroidRuntime( 843): at androidx.appcompat.app.ToolbarActionBar$ActionMenuPresenterCallback.onOpenSubMenu(ToolbarActionBar.java:560)
10-17 10:37:16.152 E/AndroidRuntime( 843): at androidx.appcompat.view.menu.BaseMenuPresenter.onSubMenuSelected(BaseMenuPresenter.java:221)
10-17 10:37:16.152 E/AndroidRuntime( 843): at androidx.appcompat.widget.ActionMenuPresenter.showOverflowMenu(ActionMenuPresenter.java:345)
10-17 10:37:16.152 E/AndroidRuntime( 843): at androidx.appcompat.widget.ActionMenuPresenter$OverflowMenuButton.performClick(ActionMenuPresenter.java:681)
10-17 10:37:16.152 E/AndroidRuntime( 843): at android.view.View.performClickInternal(View.java:6574)
10-17 10:37:16.152 E/AndroidRuntime( 843): at android.view.View.access$3100(View.java:778)
10-17 10:37:16.152 E/AndroidRuntime( 843): at android.view.View$PerformClick.run(View.java:25885)
10-17 10:37:16.152 E/AndroidRuntime( 843): at android.os.Handler.handleCallback(Handler.java:873)
10-17 10:37:16.152 E/AndroidRuntime( 843): at android.os.Handler.dispatchMessage(Handler.java:99)
10-17 10:37:16.152 E/AndroidRuntime( 843): at android.os.Looper.loop(Looper.java:193)
10-17 10:37:16.152 E/AndroidRuntime( 843): at android.app.ActivityThread.main(ActivityThread.java:6669)
10-17 10:37:16.152 E/AndroidRuntime( 843): at java.lang.reflect.Method.invoke(Native Method)
10-17 10:37:16.152 E/AndroidRuntime( 843): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
10-17 10:37:16.152 E/AndroidRuntime( 843): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Upon investigation it appears the ActionMenuPresenter invokes the callback with the null menu to indicate that the menu is opening:
// ActionMenuPresenter uses null as a callback argument here
// to indicate overflow is opening.
super.onSubMenuSelected(null);