Android:Proguard NoSuchMethodError
我最近为我的 Eclipse Android 项目激活了 ProGuard。将外部库和动态引用的类添加到 proguard.cfg 后,我在构建 apk 时没有收到任何错误。然而,当我尝试启动已安装的应用程序时,出现 NoSuchMethodError 错误。
我将其范围缩小到在主活动的 onCreate 方法中调用的特定方法。为了简化事情,类和方法如下所示(我省略了很多代码,但我认为这应该说明它):
public class TestMain extends TabActivity implements OnSharedPreferenceChangeListener{
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
testMethod();
}
}
testMethod() 定义如下:
private void testMethod() {
int charsLeft = maxPostMessageLength - someEditText.length();
...
}
当我删除“someEditText.length()”部分时,应用程序启动。所以,在我看来,找不到的方法是 EditText.length() 方法。但奇怪的是,当我从 testMethod 中删除“someEditText.length()”并将其直接放入 onCreate 方法时,应用程序也会启动:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
test = someEditText.length();
testMethod();
}
有谁知道我如何摆脱这个错误以及为什么我可以调用 someEditText.length( ) 直接在 onCreate 方法中而不是在 onCreate 方法调用的方法中? 当然,如果不使用 Proguard,该应用程序也可以正常工作。
编辑: 我尝试了 proguard.cfg 中的 -dontshrink、-dontobfuscate 和 -dontoptimzie 选项。使用 -dontoptimize 应用程序启动时不会出现错误。 尽管如此,到底是什么导致了这个特定的错误还是很有趣的。
I recently activated ProGuard for my Eclipse Android project. After adding external libs and dynamically referenced classes to the proguard.cfg, I don't get any errors when building the apk. I get however a NoSuchMethodError when I try to start the installed app.
I narrowed it down to a specific method called in the onCreate method of the main activity. To simplify things, here's what the class and method look like (I left out a lot of code, but I think this should illustrate it):
public class TestMain extends TabActivity implements OnSharedPreferenceChangeListener{
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
testMethod();
}
}
testMethod() is defined as follows:
private void testMethod() {
int charsLeft = maxPostMessageLength - someEditText.length();
...
}
When I remove the "someEditText.length()" part, the app starts. So, the way I see it, the method that can't be found is the EditText.length() method. Strangely, though, the app also starts when I remove "someEditText.length()" from the testMethod and put it directly into the onCreate method:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
test = someEditText.length();
testMethod();
}
Does anyone know how I can get rid of this error and why I can call someEditText.length() directly in the onCreate method but not in a method called by the onCreate method?
Without using Proguard the app works fine, of course.
Edit:
I tried the -dontshrink, -dontobfuscate and the -dontoptimzie options in the proguard.cfg. With -dontoptimize the app starts without errors.
Still, it would be interesting what exactly causes this specific error.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Proguard 文档自豪地指出:“ProGuard 工具通过删除未使用的代码和重命名类来缩小、优化和混淆您的代码”。
好吧,在出现您所描述的运行时错误后,我放弃了它的“缩小”部分。我将这一行添加
到了 proguard.cfg
您可以通过检查文件 use.txt 来查看哪些例程已从代码中删除。
我很高兴地说,在我的项目中它总是丢失,这意味着代码被混淆了,但没有删除任何内容。我现在没有收到任何运行时错误。
The Proguard documentation proudly states: "The ProGuard tool shrinks, optimizes, and obfuscates your code by removing unused code and renaming classes".
Well, I gave up with the 'shrinking' part of it after getting runtime errors like you describe. I added the line
to the proguard.cfg
You can see which routines have been removed from your code by inspecting the file usage.txt.
I'm happy to say that in my projects it's always missing, meaning that the code is obfuscated but nothing has been removed. I don't get any runtime errors now.
我无意中偶然发现了一个可能的解决方案。嗯,它完全适合我的情况,所以这是原始问题的解决方案:
今天,我用@Override注解实现了一些代码,一开始并没有起作用。幸运的是,其他人已经遇到了同样的问题,并且有一个简单的 Eclipse 相关解决方案:
'必须覆盖将项目导入 Eclipse 后出现“超类方法”错误
现在,我想,好吧,如果我以前总是使用 Java 级别 1.5,为什么不再次尝试 ProGuard,而不使用 -dontoptimize 选项,现在我将其设置为 1.6 。不会伤害...
我能说什么,现在应用程序启动,并且在方法中调用 EditText.length() 时我没有收到奇怪的错误。
I accidentally stumbled upon a possible solution. Well, it totally works in my case, so this IS a solution to the original problem:
Today, I implemented some code with @Override annotations, which didn't work, at first. Luckily, someone else already had the same problem and an easy Eclipse-related solution:
'Must Override a Superclass Method' Errors after importing a project into Eclipse
Now, I thought, well, if I was always using Java level 1.5 before, why not try ProGuard again, without the -dontoptimize option, now that I set it to 1.6. Can't hurt...
And what can I say, now the app starts and I don't get the strange error when EditText.length() is called in a method.
如果优化器得出的结论是该方法没有任何副作用,则可以删除该方法调用和该方法。但它永远不应该创建不一致的代码,而且我不知道这样的问题。您应该检查它是否仍然存在于最新版本的 ProGuard 中。否则,您应该在 ProGuard 站点上提交错误报告,最好提供一个说明问题的小示例。
The optimizer may remove the method invocation and the method if it comes to the conclusion that the method doesn't have any side-effects. It should never create inconsistent code though, and I'm not aware of a problem like this. You should check if it persists with the latest version of ProGuard. Otherwise, you should file a bug report on the ProGuard site, preferably with a small example that illustrates the problem.
我遇到了与OP类似的问题,它最终成为我设置-allowaccessmodification的proguard配置选项,删除它解决了问题。
I had a similar problem to the OP and it ended up being a proguard config option I set -allowaccessmodification, removing this solved the issue.