thể trùng lặp:
Removing unused strings during ProGuard optimisationLoại bỏ khai thác gỗ với ProGuard không loại bỏ các dây đang được đăng nhập
Tôi có một ứng dụng Android với hàng chục báo cáo khai thác gỗ. Tôi muốn họ sẽ không xuất hiện trong phiên bản phát hành, vì vậy tôi sử dụng Proguard với một cái gì đó như thế này trong proguard.cfg
file:
-assumenosideeffects class android.util.Log {
public static *** d(...);
}
Nhưng vấn đề là có rất nhiều Log.d("something is " + something)
, và mặc dù Log.d()
tuyên bố đang được xóa khỏi bytecode, các chuỗi vẫn còn ở đó.
Vì vậy, sau this câu trả lời, tôi đã tạo ra một lớp wrapper đơn giản, một cái gì đó dọc theo dòng:
public class MyLogger {
public static void d(Object... msgs) {
StringBuilder log = new StringBuilder();
for(Object msg : msgs) {
log.append(msg.toString());
}
Log.d(TAG, log.toString());
}
}
Sau đó, tôi thay đổi nội dung của tôi proguard.cfg
:
-assumenosideeffects class my.package.MyLogger {
public static *** d(...);
}
Nhưng chuỗi vẫn tìm thấy trong bytecode được tạo ra!
Khác với điều này, tôi đang sử dụng tiêu chuẩn proguard.cfg
do Android SDK cung cấp. Tôi có làm điều gì sai?
Sửa: sau khi kiểm tra các bytecode tạo ra, tôi thấy rằng các dây ở đó, nhưng họ không được nối với nhau như tôi nghĩ. Họ đã được được lưu trữ trong một mảng. Tại sao? Để chuyển chúng thành các tham số biến cho phương thức của tôi. Dường như ProGuard không thích điều đó, vì vậy tôi sửa đổi lớp logger của tôi như thế này:
public static void d(Object a) {
log(a);
}
public static void d(Object a, Object b) {
log(a, b);
}
(... I had to put like seven d() methods ...)
private static void log(Object... msgs) {
(same as before)
}
Nó xấu xí, nhưng bây giờ các dây là đâu trong bytecode.
Đây có phải là một số lỗi/giới hạn của ProGuard không? Hay chỉ là tôi không hiểu nó hoạt động như thế nào?
Bạn có thể muốn tránh hacks proguard và chỉ cần sử dụng một hằng số: http://stackoverflow.com/questions/4199563/android-util-log-when-publishing-what-can-i-do-not-do Nếu sau đó bạn sử dụng một proguard liên tục sẽ loại bỏ các dòng mã khi nó == false. – Blundell
Đúng là đây là một hack, và một cái xấu xí, nhưng tôi nghĩ nó tốt hơn là đặt 'if (DEBUG)' ở khắp mọi nơi. Mã kết quả là sạch hơn và kết quả là như nhau trong ứng dụng đã xuất. Ngoài ra, vì một số lý do, Eclipse đang rên rỉ về mã chết nếu hằng số gỡ lỗi là sai, và tôi không thích điều đó. Cảm ơn ý tưởng, mặc dù :) –
Lưu ý rằng vẫn có thể có một số mã chết nếu bạn chuyển các loại dữ liệu cơ bản. Proguard không loại bỏ kiểu dữ liệu cơ bản để chuyển đổi 'Object' tương ứng. Ví dụ. nếu bạn vượt qua một 'int', Proguard sẽ để lại trong dòng' Integer.valueOf (someVar); ' – crazymaik