可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
There is an issue with the Android appcompat v7 library on Samsung devices running Android 4.2. I keep getting crashes with the following stack trace in my Developer Console:
java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.MenuBuilder
at android.support.v7.widget.PopupMenu.<init>(PopupMenu.java:66)
at com.[my-package-name].CustomActivity$5.onClick(CustomActivity.java:215)
at android.view.View.performClick(View.java:4222)
at android.view.View$PerformClick.run(View.java:17620)
at android.os.Handler.handleCallback(Handler.java:800)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5391)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
This is line 215 of CustomActivity.java:
PopupMenu popup = new PopupMenu(CustomActivity.this, mImageViewMenu);
The crashes come from an array of devices, but always Samsung, and always Android 4.2.
A quick web search leads me to believe that many people have the same issue, some of the steps I have tried to solve the issue are:
- Check the Android project properties, make sure the appcompat library is added properly.
- Check the Java Build Path Order and Export project properties, make sure Android Dependencies and Android Private Libraries is checked.
- Confirm the class is included in the library (android.support.v7.internal.view.menu.MenuBuilder).
- Confirm R.java is located in gen directory for android.support.v7.appcompat.
- Confirm the AppCompat theme is included in the Manifest.xml activity.
- Clean and rebuild project.
Despite these steps, and despite it working on all other devices and Android versions the crash reports still come through.
回答1:
EDIT:
The solution that worked for me was (Using Proguard) to replace this:
-keep class android.support.v4.** { *; }
-keep interface android.support.v4.** { *; }
-keep class android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }
with this:
# Allow obfuscation of android.support.v7.internal.view.menu.**
# to avoid problem on Samsung 4.2.2 devices with appcompat v21
# see https://code.google.com/p/android/issues/detail?id=78377
-keep class !android.support.v7.internal.view.menu.**,android.support.** {*;}
Credit goes to the google group, #138.
Old answer (Temporary Workaround):
It happens in a project where I use an spinner in the ActionBar. My solution was to check for those conditions and change the app flow:
public static boolean isSamsung_4_2_2() {
String deviceMan = Build.MANUFACTURER;
String deviceRel = Build.VERSION.RELEASE;
return "samsung".equalsIgnoreCase(deviceMan) && deviceRel.startsWith("4.2.2");
}
Then in the activity's onCreate method:
if (isSamsung_4_2_2()) {
setContentView(R.layout.activity_main_no_toolbar);
} else {
setContentView(R.layout.activity_main);
}
As pointed out this is not a definitive solution, it is just a way to allow users to have access to limited functionality while a more permanent solution is found.
回答2:
As #150 from google groups said
Because careful with -keep class
!android.support.v7.internal.view.menu.**. There are a number of
classes in there which are referenced from the appcompat's resources.
The better solution is add the following lines instead:
-keep class !android.support.v7.internal.view.menu.*MenuBuilder*, android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }
回答3:
On which device you are facing this problem ? (Samsung/HTC etc.)
If it is Samsung,
Various Samsung phones are included older versions of the android support library in the framework or classpath. If you use the new material support library, you'll see this crash on those Samsung devices:
java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.MenuBuilder
To fix this, you must rename that class. Easiest way to do that is by running proguard. If you don't want to obfuscate, here's a 1 liner to rename just the offending classes:
-keep class !android.support.v7.internal.view.menu.**,** {*;}
There's an issue tracking this problem, but since it's really a Samsung bug, it's never going to get fixed on their end. Only way to fix it on the Google/AOSP side is to rename these internal classes.
https://code.google.com/p/android/issues/detail?id=78377
回答4:
This issue returned in AppCompat 23.1.1
where the .internal
package was removed from the library jar.
As suggested in the comments above (credits to the people who suggested it there), now also the proguard configuration has to change.
To get the answer suggested above working again, try adding these lines to your proguard files:
#FOR APPCOMPAT 23.1.1:
-keep class !android.support.v7.view.menu.*MenuBuilder*, android.support.v7.** { *; }
-keep interface android.support.v7.* { *; }
In stead of the old fix:
#FOR OLDER APPCOMPAT VERSION:
-keep class !android.support.v7.internal.view.menu.*MenuBuilder, android.support.v7.** { ; }
-keep interface android.support.v7.* { *; }
回答5:
According to the last posts of the bug-report, this should be fixed on the new version of the support library (24.0.0) :
https://code.google.com/p/android/issues/detail?id=78377#c374
Someone even claimed it fixed it.
This version is available since last month, so you should update to it.
回答6:
Yes. Samsung already knows about this problem.
I can suggest you try to using same implementation of Popup from GitHub. It is not best way, but will be works.
回答7:
I was having the same problem of this MenuBuilder class not found in USB debugging mode. I solved this problem by simply setting the minifyEnabled to true in both release and debug buildTypes block of build.gradle . like this:
buildTypes {
debug {
minifyEnabled true
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
I set the minifyEnabled to true in debug type to prevent app from crashing via USB debugging to a live handset.
回答8:
I enabled proguard with the default proguard properties provided with an eclipse project and the problem was fixed for me. Based on some comments here https://code.google.com/p/android/issues/detail?id=78377 , some people might have to repackage using:
-repackageclasses "android.support.v7"
回答9:
I got the same error when trying to run a 'Hello World' app on my Samsung Galaxy Tab 3 tablet via Android Studio. The app would appear to launch and then it would crash instantly and that error would show in the console in Android Studio. I did a system update on the tablet and now I am able to run the 'Hello World' app and I'm not getting the error anymore. I hope this helps someone to resolve their issue.
Note: The system update I performed on the tablet did not update the Android OS version, because it still says that the version is 4.2.2.
回答10:
Change the Compile Sdk Version of your project to "API 18:(JellyBean)"
The default is set to "Lollipop
STEPS
- Right Click on your project and select Open Module Settings (or press F4)
- In the properties tab Compiled Sdk Version