美文网首页
使用dx将class转dex总结

使用dx将class转dex总结

作者: 静默加载 | 来源:发表于2017-09-15 16:48 被阅读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的总结

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

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

    振兴书城

    相关文章

      网友评论

          本文标题:使用dx将class转dex总结

          本文链接:https://www.haomeiwen.com/subject/boossxtx.html