NoClassDefFoundError: android.support.v7.iternal.view.menu.MothyBuilder


170

Có một vấn đề với thư viện Android appcompat v7 trên các thiết bị Samsung chạy Android 4.2. Tôi liên tục gặp sự cố với theo dõi ngăn xếp sau trong Bảng điều khiển dành cho nhà phát triển của mình:

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)

Đây là dòng 215 của CustomActivity.java:

PopupMenu popup = new PopupMenu(CustomActivity.this, mImageViewMenu);

Các sự cố đến từ một loạt các thiết bị, nhưng luôn là Samsung và luôn là Android 4.2.

Một tìm kiếm trên web nhanh chóng khiến tôi tin rằng nhiều người có cùng một vấn đề, một số bước tôi đã cố gắng giải quyết vấn đề là:

  • Kiểm tra các thuộc tính dự án Android, đảm bảo thư viện appcompat được thêm đúng cách.
  • Kiểm tra các thuộc tính dự án và xuất khẩu đường dẫn xây dựng Java, đảm bảo các phụ thuộc Android và thư viện riêng của Android được kiểm tra.
  • Xác nhận lớp được bao gồm trong thư viện (android.support.v7.iternal.view.menu.MothyBuilder).
  • Xác nhận R.java nằm trong thư mục gen cho android.support.v7.appcompat.
  • Xác nhận chủ đề AppCompat được bao gồm trong hoạt động Manifest.xml.
  • Làm sạch và xây dựng lại dự án.

Mặc dù có các bước này và mặc dù nó hoạt động trên tất cả các thiết bị và phiên bản Android khác, các báo cáo sự cố vẫn xuất hiện.


4
Lưu ý: Tôi cũng đã thấy điều này xảy ra trên QMobile X25, một điện thoại cấp thấp của Pakistan. Vì vậy, có vẻ như hàu đã có cùng một cách tiếp cận hoặc cùng ROM với ROM Samsung thất bại.
William

Vì cả Google và Samsung đều không hữu ích trong việc giải quyết vấn đề HẤP DẪN này, bất kỳ ai cũng có thể nghĩ ra một giải pháp không liên quan đến Proguard (điều này làm phát sinh các vấn đề khác)?
danh sách kiểm tra

Google sẽ không làm bất cứ điều gì về nó vì Samsung dường như đã thực hiện các sửa đổi bổ sung gây ra xung đột tên giữa các thư viện. Proguard tránh va chạm. Chưa thấy giải pháp nào tốt hơn trên diễn đàn Trình theo dõi sự cố Android .
Matt K

Tôi cũng có thể thêm QMobile A290, ra khỏi Pakistan.
sstn

2
cùng một vấn đề [QMobile X30 - Android 4.4.2]
shanraisshan

Câu trả lời:


100

BIÊN TẬP:

Giải pháp hiệu quả với tôi là (Sử dụng Proguard) để thay thế:

-keep class android.support.v4.** { *; } 
-keep interface android.support.v4.** { *; }

-keep class android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }

Với cái này:

# 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.** {*;}

Tín dụng vào nhóm google, # 138 .

Câu trả lời cũ (Giải pháp tạm thời): Nó xảy ra trong một dự án nơi tôi sử dụng một công cụ quay vòng trong ActionBar. Giải pháp của tôi là kiểm tra các điều kiện đó và thay đổi luồng ứng dụng:

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");
}

Sau đó, trong phương thức onCreate của hoạt động:

if (isSamsung_4_2_2()) {
    setContentView(R.layout.activity_main_no_toolbar);
} else {
    setContentView(R.layout.activity_main);
}

Như đã chỉ ra đây không phải là một giải pháp dứt khoát, nó chỉ là một cách để cho phép người dùng có quyền truy cập vào chức năng hạn chế trong khi tìm thấy một giải pháp lâu dài hơn.


2
Bất cứ ai khác có thể xác minh câu trả lời này? Tôi không có quyền truy cập vào Samsung và ứng dụng tôi đang làm việc không còn hoạt động nữa nên tôi không thể kiểm tra.
Matt K

3
@JaredBurrows Bạn không xóa thư viện, bạn chỉ cần nói với proguard bỏ qua nó theo mặc định, với bản sửa lỗi bạn bỏ qua mọi thứ trong android.support ngoại trừ android.support.v7.i INTERNal.view.menu
thống nhất

2
Tôi đã sử dụng một giải pháp từ báo cáo vấn đề đó trong nhiều tháng nay và đột nhiên sau khi cập nhật lên các thư viện hỗ trợ mới nhất và sdk 23 Tôi đã bắt đầu nhận được báo cáo mới này về crashlytics:java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.i
casolorz

3
Vấn đề đã trở lại trong ứng dụng của tôi khi II nâng cấp lên AppCompat v23. Tôi đã phân tích tệp jar AppCompat v.23.1.1 và thấy rằng họ đã xóa thư mục "nội bộ" bên trong v7, vì vậy có vẻ như dòng lệnh Proguard bây giờ sẽ là: [-keep class! Android.support.v7.view. menu. **, android.support. ** {*;}] Tôi vẫn chưa có xác nhận từ các thử nghiệm trên thiết bị thực sự có sự cố xảy ra. Bất cứ ai có một thiết bị như vậy có thể kiểm tra điều này? Hoặc có thể việc xóa thư mục 'nội bộ' thực sự là cách khắc phục sự cố và chúng ta không cần phải gây rối với việc đổi tên lớp Proguard nữa?
gregko

7
Thêm phần này vào cài đặt proguard của bạn, nó sẽ giải quyết vấn đề: CHO APPCOMPAT 23.1.1: -keep class! Android.support.v7.view.menu. * MenuBuilder *, android.support.v7. ** { ; }-giữ giao diện android.support.v7. * { ; } ĐỐI VỚI PHIÊN BẢN APPCOMPAT: -keep class! Android.support.v7.iternal.view.menu. * MenuBuilder , android.support.v7. ** { ; }-giữ giao diện android.support.v7. * {*; }
Andrea Bellitto

26

Như # 150 từ các nhóm google đã nói

Bởi vì cẩn thận với lớp -keep! Android.support.v7.iternal.view.menu. **. Có một số lớp trong đó được tham chiếu từ tài nguyên của appcompat.

Thay vào đó, giải pháp tốt hơn là thêm các dòng sau:

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

Trong các thử nghiệm của tôi, dựa trên đánh giá về tệp ánh xạ proguard được tạo, cấu hình proguard được đề xuất này không dẫn đến việc làm xáo trộn tên lớp MenuBuilder, mặc dù nó làm xáo trộn SubMothyBuilder.
Andy Dennie

3
@William Ai đó đã xóa nó, không biết tại sao. Dù sao, đây là giải pháp của tôi: -keep class !android.support.v7.internal.view.menu.* implements android.support.v4.internal.view.SupportMenu, android.support.v7.** {*;}
Andy Dennie

3
Điều này làm việc cho tôi mà -keep class !android.support.v7.internal.view.menu.**,** {*;} không làm việc nữa với v23 của ứng dụng compat .
Quentin Klein

1
-keep class !android.support.v7.internal.view.menu.*MenuBuilder*, android.support.v7.** { *; } -keep interface android.support.v7.** { *; }như câu trả lời :)
Quentin Klein

2
trên thư viện hỗ trợ 23.1.1, các đường dẫn gói nội bộ đã được sửa đổi, vì vậy bây giờ cài đặt proguard chính xác là: -keep class! android.support.v7.view.menu. * MenuBuilder *, android.support.v7. ** { ; }-giữ giao diện android.support.v7. * {*; }
Andrea Bellitto

23

Trên thiết bị nào bạn đang phải đối mặt với vấn đề này? (Samsung / HTC, v.v.)

Nếu là Samsung,

Các điện thoại Samsung khác nhau được bao gồm các phiên bản cũ hơn của thư viện hỗ trợ Android trong khung hoặc đường dẫn lớp. Nếu bạn sử dụng thư viện hỗ trợ vật liệu mới, bạn sẽ thấy sự cố này trên các thiết bị Samsung đó:

java.lang.NoClassDefFoundError: android.support.v7.internal.view.menu.MenuBuilder

Để sửa lỗi này, bạn phải đổi tên lớp đó. Cách dễ nhất để làm điều đó là bằng cách chạy proguard. Nếu bạn không muốn làm xáo trộn, thì đây là 1 lớp lót để đổi tên chỉ các lớp vi phạm:

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

Có một vấn đề theo dõi vấn đề này, nhưng vì nó thực sự là một lỗi của Samsung, nên nó sẽ không bao giờ được sửa chữa. Cách duy nhất để sửa nó ở phía Google / AOSP là đổi tên các lớp bên trong này.

https://code.google.com.vn/p/android/issues/detail?id=78377


Bạn có sử dụng proguard để hỗ trợ v4 không?
Jared Burrows

@JaredBurrows Tôi đã thử hỗ trợ v7. Nhưng đối với v4 nó cũng sẽ hoạt động.
Ganesh AB - Android

2
@ Android007: cảm ơn bạn đã chỉ ra rằng công việc xung quanh thực sự hoạt động. Tuy nhiên, dường như không ai có thể giải thích lý do tại sao các ROM bị lỗi nhúng Thư viện hỗ trợ Android cũ trong bootgrouppath của họ gây ra ngoại lệ này do lớp "android.support.v7.i INTERNal.view.menu.MothyBuilder" bị thiếu có sẵn trong. Mã DEX của ứng dụng bị sự cố này. Bạn có thể có bất kỳ con trỏ nào trong tay giải thích cách thức thời gian chạy Android tải các lớp được lấy từ các tệp jar / dex của bootgrouppath và ứng dụng không? Hoặc bất kỳ lời giải thích chính xác, xin vui lòng?
Édouard Mercier

@ ÉdouardMercier Xin lỗi vì đã trả lời trễ. Hiện tại tôi không có câu trả lời nào cho câu hỏi của bạn nhưng tôi sẽ liên lạc lại với bạn sớm. :)
Ganesh AB - Android

Cảm ơn bạn @ Android007, với tư cách là bất kỳ lập trình viên nào, tôi không thích phù thủy lắm;) Một gợi ý: liệu bootgrouppath nhúng có chứa "kín" .jar / .dex, sẽ giải thích cho hành vi không?
Édouard Mercier

15

Vấn đề này được trả về trong AppCompat 23.1.1đó .internalgói đã bị xóa khỏi thư viện jar.

Như được đề xuất trong các ý kiến ​​trên (tín dụng cho những người đề xuất nó ở đó), bây giờ cũng cấu hình proguard phải thay đổi.

Để có câu trả lời được đề xuất ở trên hoạt động trở lại, hãy thử thêm các dòng này vào tệp proguard của bạn:

#FOR APPCOMPAT 23.1.1:
-keep class !android.support.v7.view.menu.*MenuBuilder*, android.support.v7.** { *; }
-keep interface android.support.v7.* { *; }

Thay cho bản sửa lỗi cũ:

#FOR OLDER APPCOMPAT VERSION:
-keep class !android.support.v7.internal.view.menu.*MenuBuilder, android.support.v7.** { ; }
-keep interface android.support.v7.* { *; }

!android.support.v7.view.menu.**an toàn hơn vì các lớp khác như SubMothyBuilder
JaredBopes 17/03/2016

12

Theo các bài đăng cuối cùng của báo cáo lỗi, điều này cần được sửa trên phiên bản mới của thư viện hỗ trợ (24.0.0): https://code.google.com.vn/p/android/issues/detail?id=78377 # c374

Thậm chí có người tuyên bốđã sửa nó.

Phiên bản này có sẵn từ tháng trước , vì vậy bạn nên cập nhật nó.


Thử nghiệm của chúng tôi xác nhận rằng 24.0.0 khắc phục sự cố. Chúng tôi đã nâng cấp thư viện hỗ trợ lên 24.0.0 (không phải alpha), loại bỏ obfuscation mà chúng tôi đang sử dụng như một cách giải quyết và không thấy sự cố nào trên thiết bị thử nghiệm của Samsung, nơi chúng tôi đã thấy sự cố trước đó.
Đánh dấu McClelland

4

Đúng. Samsung đã biết về vấn đề này . Tôi có thể đề nghị bạn thử sử dụng cùng một triển khai Popup từ GitHub . Đó không phải là cách tốt nhất, nhưng sẽ là công việc.


1
Có, tôi đã thấy điều đó trên diễn đàn Samsung nhưng có vẻ như họ không quan tâm vì không có đại diện hay bộ phận hỗ trợ nào của họ trả lời.
Matt K

4

Tôi đã gặp vấn đề tương tự của lớp MenuBuilder này không tìm thấy trong chế độ gỡ lỗi USB. Tôi giải quyết vấn đề này bằng cách đơn giản thiết lập minifyEnabled để đúng trong cả hai phiên bản và debug buildTypes khối build.gradle . như thế này:

buildTypes {

    debug {

        minifyEnabled true
    }

    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

Tôi đặt minifyEnables thành true trong loại gỡ lỗi để ngăn ứng dụng gặp sự cố thông qua gỡ lỗi USB cho thiết bị cầm tay trực tiếp.


0

Tôi đã kích hoạt proguard với các thuộc tính proguard mặc định được cung cấp với dự án nhật thực và sự cố đã được khắc phục cho tôi. Dựa trên một số nhận xét tại đây https://code.google.com.vn/p/android/issues/detail?id=78377 , một số người có thể phải đóng gói lại bằng cách sử dụng: -repackagec Cầu "android.support.v7"


Có vẻ như điều đó không hiệu quả với hầu hết mọi người trong diễn đàn. Có vẻ như quay trở lại appcompat-20 là một lựa chọn đáng tin cậy hơn.
Matt K

Điều này được cho là đã được giải quyết trong hỗ trợ v23.1.1
Tim Malseed

0

Tôi đã gặp lỗi tương tự khi thử chạy ứng dụng 'Hello World' trên máy tính bảng Samsung Galaxy Tab 3 của tôi thông qua Android Studio. Ứng dụng sẽ xuất hiện để khởi chạy và sau đó nó sẽ bị sập ngay lập tức và lỗi đó sẽ hiển thị trong bảng điều khiển trong Android Studio. Tôi đã thực hiện cập nhật hệ thống trên máy tính bảng và bây giờ tôi có thể chạy ứng dụng 'Hello World' và tôi không gặp lỗi nữa. Tôi hy vọng điều này sẽ giúp ai đó giải quyết vấn đề của họ.

Lưu ý: Bản cập nhật hệ thống tôi thực hiện trên máy tính bảng không cập nhật phiên bản HĐH Android, vì vẫn nói rằng phiên bản này là 4.2.2.


-4

Thay đổi Phiên bản biên dịch Sdk của dự án của bạn thành "API 18: (JellyBean)"

Mặc định được đặt thành "Lollipop

BƯỚC

  1. Nhấp chuột phải vào dự án của bạn và chọn Mở Cài đặt mô-đun (hoặc nhấn F4)
  2. Trong tab thuộc tính Phiên bản Sdk được biên dịch
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.