使用dx將class轉(zhuǎn)dex總結(jié)

dx簡述

dx工具是一種用來轉(zhuǎn)換Java class成為DEX格式的工具。多個類被包含在一個dex文件之中。各個類中重復(fù)的字符串和其他常數(shù)只在DEX中存放一次,以節(jié)省空間。Java字節(jié)碼(bytecode)被轉(zhuǎn)換成Dalvik虛擬機所使用的替代指令集。一個未壓縮dex文件通常稍小于一個已經(jīng)壓縮的.jar檔(摘自維基百科)。

轉(zhuǎn)化結(jié)果

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的版本不同導(dǎo)致的。
辦法:在低版本的/Sdk/build-tools/x.x.x/目錄下執(zhí)行java javac -source 1.6 -target 1.6 xx.java 這樣得到的class文件在進行dex轉(zhuǎn)化的時候才不會報錯。如果這樣處理還報錯那么請看看問題三。

問題三:

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的總結(jié)

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容