我有一个大函数(我知道,见下文)在优化过程中破坏了proguard。我想保留长函数和优化。这可能吗?有没有办法说服proguard处理更大的功能?
代码在Eclipse下编译并在Android设备上运行。这是我发布构建脚本的proguard优化步骤失败了。如果我从函数中删除30行奇数行,它可以正常构建,但显然不能正确运行。
我的大函数是一个模拟状态机的开关函数。大约有五个独立但相关的变量,它们会随着状态机的进展以不同的方式进行调整。我可以拆分我的函数,但是子函数之间的耦合是不可取的。
空指针异常的堆栈跟踪是:
[proguard] Shrinking...
[proguard] Removing unused program classes and class elements...
[proguard] Original number of program classes: 176
[proguard] Final number of program classes: 173
[proguard] Optimizing...
[proguard] Unexpected error while evaluating instruction:
[proguard] Class = [com/.../Screen]
[proguard] Method = [switchToView$26d62a66(Lcom/...;Ljava/lang/String;)V]
[proguard] Instruction = [20] iload v4
[proguard] Exception = [java.lang.NullPointerException] (null)
[proguard] Unexpected error while performing partial evaluation:
[proguard] Class = [com/.../Screen]
[proguard] Method = [switchToView$26d62a66(Lcom/.../View;Ljava/lang/String;)V]
[proguard] Exception = [java.lang.NullPointerException] (null)
BUILD FAILED
/Users/colin/Android/.../build.xml:527: java.lang.NullPointerException
at proguard.evaluation.Variables.iload(Variables.java:228)
at proguard.evaluation.Processor.visitVariableInstruction(Processor.java:645)
at proguard.classfile.instruction.VariableInstruction.accept(VariableInstruction.java:306)
at proguard.optimize.evaluation.PartialEvaluator.evaluateSingleInstructionBlock(PartialEvaluator.java:729)
at proguard.optimize.evaluation.PartialEvaluator.evaluateInstructionBlock(PartialEvaluator.java:575)
at proguard.optimize.evaluation.PartialEvaluator.visitExceptionInfo(PartialEvaluator.java:1063)
at proguard.classfile.visitor.ExceptionHandlerFilter.visitExceptionInfo(ExceptionHandlerFilter.java:67)
at proguard.classfile.attribute.CodeAttribute.exceptionsAccept(CodeAttribute.java:186)
at proguard.optimize.evaluation.PartialEvaluator.evaluateExceptionHandlers(PartialEvaluator.java:1003)
at proguard.optimize.evaluation.PartialEvaluator.evaluateInstructionBlockAndExceptionHandlers(PartialEvaluator.java:540)
at proguard.optimize.evaluation.PartialEvaluator.visitCodeAttribute0(PartialEvaluator.java:221)
at proguard.optimize.evaluation.PartialEvaluator.visitCodeAttribute(PartialEvaluator.java:180)
at proguard.optimize.evaluation.LivenessAnalyzer.visitCodeAttribute(LivenessAnalyzer.java:195)
at proguard.optimize.evaluation.VariableOptimizer.visitCodeAttribute(VariableOptimizer.java:102)
at proguard.classfile.attribute.CodeAttribute.accept(CodeAttribute.java:101)
at proguard.classfile.ProgramMethod.attributesAccept(ProgramMethod.java:79)
at proguard.classfile.attribute.visitor.AllAttributeVisitor.visitProgramMember(AllAttributeVisitor.java:95)
at proguard.classfile.util.SimplifiedVisitor.visitProgramMethod(SimplifiedVisitor.java:91)
at proguard.classfile.ProgramMethod.accept(ProgramMethod.java:71)
at proguard.classfile.ProgramClass.methodsAccept(ProgramClass.java:439)
at proguard.classfile.visitor.AllMethodVisitor.visitProgramClass(AllMethodVisitor.java:47)
at proguard.classfile.ProgramClass.accept(ProgramClass.java:281)
at proguard.classfile.ClassPool.classesAccept(ClassPool.java:114)
at proguard.optimize.Optimizer.execute(Optimizer.java:764)
at proguard.ProGuard.optimize(ProGuard.java:325)
at proguard.ProGuard.execute(ProGuard.java:114)
at proguard.ant.ProGuardTask.execute(ProGuardTask.java:279)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:68)
at com.android.ant.IfElseTask.execute(IfElseTask.java:120)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
at sun.reflect.GeneratedMethodAccessor4.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
at org.apache.tools.ant.Task.perform(Task.java:348)
at org.apache.tools.ant.Target.execute(Target.java:390)
at org.apache.tools.ant.Target.performTasks(Target.java:411)
at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
at org.apache.tools.ant.Main.runBuild(Main.java:809)
at org.apache.tools.ant.Main.startAnt(Main.java:217)
at org.apache.tools.ant.launch.Launcher.run(Launcher.java:280)
at org.apache.tools.ant.launch.Launcher.main(Launcher.java:109)
优化长方法可能需要很长时间,但它不应该失败。这个错误信息表明ProGuard中存在错误。您应该检查它是否在最新版本(撰写本文时为4.6)中没有得到修复。否则,你应该在ProGuard的bug跟踪器上报告它。如果您能提供一个测试用例,让我重现这个问题,我将研究一下。