[英]What am I missing in this Proguard configuration for Android?
我已经尝试了无数的东西但是我无法阻止我的应用程序在使用Proguard缩小代码时崩溃(混淆被禁用)。 启用Proguard时,我总是遇到以下异常:
04-03 10:26:37.277 E/AndroidRuntime(29460): FATAL EXCEPTION: main
04-03 10:26:37.277 E/AndroidRuntime(29460): java.lang.ExceptionInInitializerError
04-03 10:26:37.277 E/AndroidRuntime(29460): at com.company.nativeapp.activitycontrollers.LoginController.onLogInSuccess(LoginController.java:199)
04-03 10:26:37.277 E/AndroidRuntime(29460): at com.company.datamanager.BfAccountStateManager$AccountWebViewClient.shouldOverrideUrlLoading(BfAccountStateManager.java:326)
04-03 10:26:37.277 E/AndroidRuntime(29460): at android.webkit.CallbackProxy.uiOverrideUrlLoading(CallbackProxy.java)
04-03 10:26:37.277 E/AndroidRuntime(29460): at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java)
04-03 10:26:37.277 E/AndroidRuntime(29460): at android.os.Handler.dispatchMessage(Handler.java)
04-03 10:26:37.277 E/AndroidRuntime(29460): at android.os.Looper.loop(Looper.java)
04-03 10:26:37.277 E/AndroidRuntime(29460): at android.app.ActivityThread.main(ActivityThread.java)
04-03 10:26:37.277 E/AndroidRuntime(29460): at java.lang.reflect.Method.invokeNative(Native Method)
04-03 10:26:37.277 E/AndroidRuntime(29460): at java.lang.reflect.Method.invoke(Method.java:511)
04-03 10:26:37.277 E/AndroidRuntime(29460): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
04-03 10:26:37.277 E/AndroidRuntime(29460): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:795)
04-03 10:26:37.277 E/AndroidRuntime(29460): at dalvik.system.NativeStart.main(Native Method)
04-03 10:26:37.277 E/AndroidRuntime(29460): Caused by: java.lang.ExceptionInInitializerError
04-03 10:26:37.277 E/AndroidRuntime(29460): at com.company.android.bfsdk.diffusion.requests.mcs.BaseMCSRequest.<clinit>(BaseMCSRequest.java:28)
04-03 10:26:37.277 E/AndroidRuntime(29460): ... 12 more
04-03 10:26:37.277 E/AndroidRuntime(29460): Caused by: java.lang.ExceptionInInitializerError
04-03 10:26:37.277 E/AndroidRuntime(29460): at com.company.mobile.mcs.service.descriptor.inplay.Inplay.<clinit>(Inplay.java:20585)
04-03 10:26:37.277 E/AndroidRuntime(29460): ... 13 more
04-03 10:26:37.277 E/AndroidRuntime(29460): Caused by: java.lang.RuntimeException: Generated message class "com.company.mobile.mcs.service.descriptor.Mcs$MCSRequestMessage$Builder" missing method "getUserAgent".
04-03 10:26:37.277 E/AndroidRuntime(29460): at com.google.protobuf.GeneratedMessage.getMethodOrDie(GeneratedMessage.java:1359)
04-03 10:26:37.277 E/AndroidRuntime(29460): at com.google.protobuf.GeneratedMessage.access$1300(GeneratedMessage.java:57)
04-03 10:26:37.277 E/AndroidRuntime(29460): at com.google.protobuf.GeneratedMessage$FieldAccessorTable$SingularFieldAccessor.<init>(GeneratedMessage.java:1485)
04-03 10:26:37.277 E/AndroidRuntime(29460): at com.google.protobuf.GeneratedMessage$FieldAccessorTable.<init>(GeneratedMessage.java:1432)
04-03 10:26:37.277 E/AndroidRuntime(29460): at com.company.mobile.mcs.service.descriptor.Mcs$1.assignDescriptors(Mcs.java:2083)
04-03 10:26:37.277 E/AndroidRuntime(29460): at com.google.protobuf.Descriptors$FileDescriptor.internalBuildGeneratedFileFrom(Descriptors.java:298)
04-03 10:26:37.277 E/AndroidRuntime(29460): at com.company.mobile.mcs.service.descriptor.Mcs.<clinit>(Mcs.java:2109)
04-03 10:26:37.277 E/AndroidRuntime(29460): ... 14 more
04-03 10:26:37.277 E/AndroidRuntime(29460): Caused by: java.lang.NoSuchMethodException: getUserAgent []
04-03 10:26:37.277 E/AndroidRuntime(29460): at java.lang.Class.getConstructorOrMethod(Class.java:460)
04-03 10:26:37.277 E/AndroidRuntime(29460): at java.lang.Class.getMethod(Class.java:915)
04-03 10:26:37.277 E/AndroidRuntime(29460): at com.google.protobuf.GeneratedMessage.getMethodOrDie(GeneratedMessage.java:1357)
04-03 10:26:37.277 E/AndroidRuntime(29460): ... 20 more
除了Android应用程序的标准Proguard配置外,我还添加了以下几行:
-keep public class com.company.**
-keep class com.company.* { *; }
-keepclassmembernames class com.company.* { *; }
-keep class * extends com.google.protobuf.GeneratedMessage { *; }
-keepclassmembernames class * extends com.google.protobuf.GeneratedMessage { *; }
但我仍然得到上面提到的例外......
我错过了什么?
问题是ProtocolBuffers使用反射调用方法,但Proguard无法看到反射调用。 Proguard可以更改方法/对象的名称或删除方法/对象,无论是反射都找不到它。
选项:
您可以尝试查找每个可能的反射调用并添加适当的Proguard语句。但是您可能需要为每个新版本的协议缓冲区更改此值。 我个人不会这样
您可以尝试将optimize_for SPEED选项添加到Proto Definition并重新生成java代码,这将导致更大的类不使用反射并且可以与Proguard一起使用。
尝试使用JavaMe protobuf解决方案之一 - 它们要小得多。 看上一个问题
问题代码:
private static Method getMethodOrDie(
final Class clazz, final String name, final Class... params) {
try {
return clazz.getMethod(name, params);
} catch (NoSuchMethodException e) {
throw new RuntimeException(
"Generated message class \"" + clazz.getName() +
"\" missing method \"" + name + "\".", e);
}
}
我也遇到过这个问题:java.lang.RuntimeException在签名的apk中生成的消息类“xxx”缺少方法“xxx”,但在调试模式下它是不可能的。 我确信Proguard配置没问题。
通过分析堆栈跟踪日志,我找到了问题的根本原因:打印protobuf文件日志太大了,比如
List<UserPb.UserInfo> userInfos = obj.getUserInfoList();
Log.d(TAG, "userInfos: " + userInfos);
这个UserPb.java文件非常庞大,包含超过50000行代码。
因此, 请勿在签名的apk中打印protobuf相关的日志 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.