当我使用Proguard编译我的Android应用程序时,我收到以下错误:
-dex:
[echo] Converting compiled files and external libraries into /home/ka/dev/workspace/ImPress/build/classes.dex...
[apply]
[apply] UNEXPECTED TOP-LEVEL EXCEPTION:
[apply] com.android.dx.cf.code.SimException: local variable type mismatch: attempt to set or access a value of type java.io.File using a local variable of type java.lang.Object[]. This is symptomatic of .class transformation tools that ignore local variable information.
[apply] at com.android.dx.cf.code.BaseMachine.throwLocalMismatch(BaseMachine.java:550)
[apply] at com.android.dx.cf.code.BaseMachine.getLocalTarget(BaseMachine.java:405)
[apply] at com.android.dx.cf.code.BaseMachine.storeResults(BaseMachine.java:532)
[apply] at com.android.dx.cf.code.ValueAwareMachine.run(ValueAwareMachine.java:197)
[apply] at com.android.dx.cf.code.RopperMachine.run(RopperMachine.java:291)
[apply] at com.android.dx.cf.code.Simulator$SimVisitor.visitLocal(Simulator.java:608)
[apply] at com.android.dx.cf.code.BytecodeArray.parseInstruction(BytecodeArray.java:526)
[apply] at com.android.dx.cf.code.Simulator.simulate(Simulator.java:99)
[apply] at com.android.dx.cf.code.Ropper.processBlock(Ropper.java:684)
[apply] at com.android.dx.cf.code.Ropper.doit(Ropper.java:639)
[apply] at com.android.dx.cf.code.Ropper.convert(Ropper.java:252)
[apply] at com.android.dx.dex.cf.CfTranslator.processMethods(CfTranslator.java:252)
[apply] at com.android.dx.dex.cf.CfTranslator.translate0(CfTranslator.java:131)
[apply] at com.android.dx.dex.cf.CfTranslator.translate(CfTranslator.java:85)
[apply] at com.android.dx.command.dexer.Main.processClass(Main.java:369)
[apply] at com.android.dx.command.dexer.Main.processFileBytes(Main.java:346)
[apply] at com.android.dx.command.dexer.Main.access$400(Main.java:59)
[apply] at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:294)
[apply] at com.android.dx.cf.direct.ClassPathOpener.processArchive(ClassPathOpener.java:244)
[apply] at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:130)
[apply] at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:108)
[apply] at com.android.dx.command.dexer.Main.processOne(Main.java:313)
[apply] at com.android.dx.command.dexer.Main.processAllFiles(Main.java:233)
[apply] at com.android.dx.command.dexer.Main.run(Main.java:185)
[apply] at com.android.dx.command.dexer.Main.main(Main.java:166)
[apply] at com.android.dx.command.Main.main(Main.java:90)
[apply] ...at bytecode offset 00000006
[apply] locals[0000]: Lcom/officemax/impress/ui/library/task/DocumentBrowserTask;
[apply] locals[0001]: [Ljava/lang/Object;
[apply] locals[0002]: <invalid>
[apply] ...while working on block 0006
[apply] ...while working on method doTaskJob:([Ljava/lang/Object;)Lcom/kaciula/utils/ui/BasicTaskResponse;
[apply] ...while processing doTaskJob ([Ljava/lang/Object;)Lcom/kaciula/utils/ui/BasicTaskResponse;
[apply] ...while processing com/officemax/impress/ui/library/task/DocumentBrowserTask.class
[apply]
[apply] 1 error; aborting
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个问题?
plo*_*man 98
在我的proguard.cfg文件中添加-dontobfuscate标志后,我遇到了同样的问题.
最终解决方案是我需要将其添加到我的优化中:
!code/allocation/variable
Run Code Online (Sandbox Code Playgroud)
这使我的完整优化字符串看起来像这样:
-optimizations !field/removal/writeonly,!field/marking/private,!class/merging/*,!code/allocation/variable
Run Code Online (Sandbox Code Playgroud)
Eri*_*une 22
这是ProGuard中的一个错误.其优化步骤有时不会完全正确地更新类文件中的可选"LocalVariableTable"和"LocalVariableTypeTable"调试属性.Dalvik VM显式检查调试属性,如果类文件不一致则拒绝它们.
您应该检查最新版本的ProGuard是否修复了该问题.否则,您应该从类文件中删除局部变量名称和类型.您可以要求java编译器不生成它们(例如"javac -g:none").您也可以要求ProGuard不要保留它们(不要指定"-keepattributes LocalVariableTable,LocalVariableTypeTable").
pjv*_*pjv 15
实际的Proguard部分完成,但是dex不能再转换生成的字节码.Dex认为LocalVariableTable不正确.Eric Lafortune是解释原因的更好来源(见他的回答).
如果您不仅不进行模糊处理,而且还跳过优化步骤(-dontoptimize),问题就会消失.但是你想要减小尺寸.另一种解决方法是将调试标志放入javac和放入dex.唯一的问题是,你也没有适当的堆栈跟踪.您将获得没有源文件信息或行号的stacktrace行,例如:
net.lp.collectionista.domain.items.book.BookItem.getCoverImageForFormField(Unkno??wn Source)
Run Code Online (Sandbox Code Playgroud)
您可以通过debug="false"在javacant中添加标记来执行此操作main-rules.xml(您可能希望将该部分复制到build.xml第一个).这将设置一个标志javac -g:none.您还必须配置dex,这在提供的ant模板中更难做到.我复制了dex-helper宏,确保它被使用,并在dex调用周围添加了一个条件标记:
<echo>Converting compiled files and external libraries into ${intermediate.dex.file}...</echo>
<if condition="debug">
<then>
<apply executable="${dx}" failonerror="true" parallel="true">
<arg value="--dex" />
<arg value="--output=${intermediate.dex.file}" />
<extra-parameters />
<arg line="${verbose.option}" />
<arg path="${out.dex.input.absolute.dir}" />
<path refid="out.dex.jar.input.ref" />
<external-libs />
</apply>
</then>
<else>
<apply executable="${dx}" failonerror="true" parallel="true">
<arg value="--dex" />
<arg value="--output=${intermediate.dex.file}" />
<arg value="--no-locals" /><!-- otherwise dex fails on the proguard bytecode -->
<extra-parameters />
<arg line="${verbose.option}" />
<arg path="${out.dex.input.absolute.dir}" />
<path refid="out.dex.jar.input.ref" />
<external-libs />
</apply>
</else>
</if>
Run Code Online (Sandbox Code Playgroud)
这就是--no-locals它.
为了减少堆栈跟踪信息的丢失,您可以分别使用行号信息和类和方法名称信息:
-keepattributes SourceFile, LineNumberTable
-keep,allowshrinking,allowoptimization class * { <methods>; }
Run Code Online (Sandbox Code Playgroud)
这样你就可以进行部分混淆,并且仍然具有相同的良好堆栈跟踪.我仍然建议您在发布时创建并保留映射文件.
除此之外,你不应该-keepattributes LocalVariableTable,LocalVariableTypeTable同样指定-keepparameternames(如果你做混淆,这本身可能会让你陷入麻烦).请注意,第二个意味着第一个,即使它的名称可能不清楚它会影响属性.
就个人而言,鉴于Proguard的其他问题,我选择进行混淆,但减少了堆栈跟踪信息的丢失.我还没有试过@plowman的提议.
有关详细信息,您可以在此处找到我的版本控制项目文件:
| 归档时间: |
|
| 查看次数: |
19632 次 |
| 最近记录: |