更新到Support Tools 23后,再次出现java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.i。

9
我曾经实施了在https://code.google.com/p/android/issues/detail?id=78377上列出的众多解决方案之一,以解决4.2.2手机的问题。但现在我已升级到支持工具23,这个问题又回来了。如果您查看该问题报告,您会发现自更新后有很多人都遇到了同样的问题。在NoClassDefFoundError: android.support.v7.internal.view.menu.MenuBuilder上的解决方案也不可行,因为它们来自于https://code.google.com/p/android/issues/detail?id=78377

这是我得到的异常:

java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.i
       at android.support.v7.widget.ActionMenuView.getMenu(ActionMenuView.java:643)
       at android.support.v7.widget.Toolbar.ensureMenu(Toolbar.java:876)
       at android.support.v7.widget.Toolbar.getMenu(Toolbar.java:847)
       at android.support.v7.internal.widget.ToolbarWidgetWrapper.getMenu(ToolbarWidgetWrapper.java:702)
       at android.support.v7.internal.app.ToolbarActionBar.getMenu(ToolbarActionBar.java:583)
       at android.support.v7.internal.app.ToolbarActionBar.populateOptionsMenu(ToolbarActionBar.java:441)
       at android.support.v7.internal.app.ToolbarActionBar$1.run(ToolbarActionBar.java:65)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776)
       at android.view.Choreographer.doCallbacks(Choreographer.java:579)
       at android.view.Choreographer.doFrame(Choreographer.java:547)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762)
       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(Method.java)
       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(NativeStart.java)

我的Proguard文件如下:

-keep class !android.support.v7.internal.view.menu.**,android.support.** {*;}

有什么解决方案吗?我们收到了很多用户的投诉。

我也是,在添加后仍然遇到了相同的问题。设备运行4.2.2。 - Mikey
1个回答

5

您的ProGuard“保留类”规则需要更新,因为目标类不再被混淆。在支持工具的23版中,Google将与菜单相关的类移出了内部包。我可以确认以下ProGuard规则消除了在某些运行Android 4.2.2的三星设备上看到的NoClassDefFoundError。

# Workaround for conflict with certain OEM-modified versions of the Android appcompat
# support libs, especially Samsung + Android 4.2.2
# See this thread for more info:
#   https://code.google.com/p/android/issues/detail?can=2&start=0&num=100&q=&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&groupby=&sort=&id=78377
-keepattributes **
# Keep all classes except the ones indicated by the patterns preceded by an exclamation mark
-keep class !android.support.v7.view.menu.**,!android.support.design.internal.NavigationMenu,!android.support.design.internal.NavigationMenuPresenter,!android.support.design.internal.NavigationSubMenu,** {*;}
# Skip preverification
-dontpreverify
# Specifies not to optimize the input class files
-dontoptimize
# Specifies not to shrink the input class files
-dontshrink
# Specifies not to warn about unresolved references and other important problems at all
-dontwarn **
# Specifies not to print notes about potential mistakes or omissions in the configuration, such as
# typos in class names or missing options that might be useful
-dontnote **

我强烈建议您使用dex2jar和jd来确认所需的混淆已经发生(在这里描述:https://dev59.com/i2kw5IYBdhLWcg3wBl-A#10191338)。不幸的是,每次升级支持工具时都需要进行此操作,以防包被移动或重新命名。

Google将类移到“internal”包之外,希望这样可以避免导致NoClassDefFoundError的类路径冲突。然而,正如Chris Banes在此错误线程中所述(https://code.google.com/p/android/issues/detail?id=78377),他们并没有测试来验证修复 -- 许多人后来报告了您看到的同样的崩溃:

没错,我们已经决定对内部类进行一次重命名, 这应该会修复它。但是我没有在这些设备上进行任何测试, 也不打算进行任何测试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接