使用dx将class转dex总结

2017-09-15  本文已影响494人  静默加载

个人博客地址 http://dandanlove.com/

dx简述

dx工具是一种用来转换Java class成为DEX格式的工具。多个类被包含在一个dex文件之中。各个类中重复的字符串和其他常数只在DEX中存放一次,以节省空间。Java字节码(bytecode)被转换成Dalvik虚拟机所使用的替代指令集。一个未压缩dex文件通常稍小于一个已经压缩的.jar档(摘自维基百科)。

转化结果

Demo.java

tanzhenxing@tanzhenxing:~/android/Sdk/build-tools/22.0.1$ cat Demo.java 
/**
 * Created by tanzhenxing on 17-9-15.
 */
public class Demo {
    public static void foo() {
        int a = 1;
        int b = 2;
        int c = (a + b) * 5;
    }
}

Demo.class

tanzhenxing@tanzhenxing:~/android/Sdk/build-tools/22.0.1$ javap -c Demo.class 
Compiled from "Demo.java"
public class Demo {
  public Demo();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void foo();
    Code:
       0: iconst_1
       1: istore_0
       2: iconst_2
       3: istore_1
       4: iload_0
       5: iload_1
       6: iadd
       7: iconst_5
       8: imul
       9: istore_2
      10: return
}

Demo.dex

tanzhenxing@tanzhenxing:~/android/Sdk/build-tools/22.0.1$ ./dexdump -d Demo.dex 
Processing 'Demo.dex'...
Opened 'Demo.dex', DEX version '035'
Class #0            -
  Class descriptor  : 'LDemo;'
  Access flags      : 0x0001 (PUBLIC)
  Superclass        : 'Ljava/lang/Object;'
  Interfaces        -
  Static fields     -
  Instance fields   -
  Direct methods    -
    #0              : (in LDemo;)
      name          : '<init>'
      type          : '()V'
      access        : 0x10001 (PUBLIC CONSTRUCTOR)
      code          -
      registers     : 1
      ins           : 1
      outs          : 1
      insns size    : 4 16-bit code units
0000d8:                                        |[0000d8] Demo.<init>:()V
0000e8: 7010 0200 0000                         |0000: invoke-direct {v0}, Ljava/lang/Object;.<init>:()V // method@0002
0000ee: 0e00                                   |0003: return-void
      catches       : (none)
      positions     : 
        0x0000 line=4
      locals        : 
        0x0000 - 0x0004 reg=0 this LDemo; 

    #1              : (in LDemo;)
      name          : 'foo'
      type          : '()V'
      access        : 0x0009 (PUBLIC STATIC)
      code          -
      registers     : 0
      ins           : 0
      outs          : 0
      insns size    : 1 16-bit code units
0000f0:                                        |[0000f0] Demo.foo:()V
000100: 0e00                                   |0000: return-void
      catches       : (none)
      positions     : 
        0x0000 line=9
      locals        : 

  Virtual methods   -
  source_file_idx   : 1 (Demo.java)

遇到的问题

问题一:

trouble processing:
bad class file magic (cafebabe) or version (0034.0000)
...while parsing Demo.class
...while processing Demo.class
1 warning
no classfiles specified

问题二

UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dx.cf.iface.ParseException: bad class file magic (cafebabe) or version (0034.0000)
    at com.android.dx.cf.direct.DirectClassFile.parse0(DirectClassFile.java:472)
    at com.android.dx.cf.direct.DirectClassFile.parse(DirectClassFile.java:406)
    at com.android.dx.cf.direct.DirectClassFile.parseToInterfacesIfNecessary(DirectClassFile.java:388)
    at com.android.dx.cf.direct.DirectClassFile.getMagic(DirectClassFile.java:251)
    at com.android.dx.command.dexer.Main.processClass(Main.java:704)
    at com.android.dx.command.dexer.Main.processFileBytes(Main.java:673)
    at com.android.dx.command.dexer.Main.access$300(Main.java:83)
    at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:602)
    at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:170)
    at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:144)
    at com.android.dx.command.dexer.Main.processOne(Main.java:632)
    at com.android.dx.command.dexer.Main.processAllFiles(Main.java:510)
    at com.android.dx.command.dexer.Main.runMonoDex(Main.java:280)
    at com.android.dx.command.dexer.Main.run(Main.java:246)
    at com.android.dx.command.dexer.Main.main(Main.java:215)
    at com.android.dx.command.Main.main(Main.java:106)
...while parsing Demo.class

解决办法:

原因:其实问题一和问题二都是因为编译class文件的jdk版本和Android的dx的版本不同导致的。
办法:在低版本的/Sdk/build-tools/x.x.x/目录下执行java javac -source 1.6 -target 1.6 xx.java 这样得到的class文件在进行dex转化的时候才不会报错。如果这样处理还报错那么请看看问题三。

问题三:

trouble processing:
class name (com/loadclass/demo/Demo) does not match path (Demo.class)
...while parsing Demo.class
...while processing Demo.class
1 warning
no classfiles specified

解决办法:

去掉java类文件中的包名;

参考:dx编译Hello.java的总结

文章到这里就全部讲述完啦,若有其他需要交流的可以留言哦

想阅读作者的更多文章,可以查看我 个人博客 和公共号:

振兴书城
上一篇下一篇

猜你喜欢

热点阅读