.java生成dex文件

参考:http://www.android100.org/html/201502/26/123364.html

首先第一个是 jar 文件的制作,Java 里面直接把 .class 文件打包到 .jar 文件里面就可以了,但是 Android 的 Dalvik VM 是不认 Java 的 byte code 的,所以不能直接这么打包,而要用 dx 工具转成 Dalvik byte code 才可以。当然,dx 工具转了之后,jar 包里面就不 是 .class 文件了,而是 .dex 文件。

第二个是,Android 里面虽然也提供了 URLClassLoader 的实现,但是并不能用。要动态加载其它类,可以用的 Class Loader 有: 
DexClassLoader,PathClassLoader,其中,DexClassLoader 可以加载 apk, jar 或者 dex 文件,例如: 

代码如下:

File jarFile = new File("/sdcard/test.dex"); 
# if ( jarFile.exists() ) { 
DexClassLoader cl = new DexClassLoader(jarFile.toString(), "/sdcard/test", null, ClassLoader.getSystemClassLoader()); 
Class<?> c = cl.loadClass("xiaogang.test.Test"); 


但是 DexClassLoader 要求指定一个可写的目录,即 DexClassLoader 构造函数的第二个参数,在上例中是 /sdcard/test 
这个参数的含义是:directory where optimized DEX files should be written 
因为 Dalvik 在加载 dex 文件时,会动态进行优化,DexClassLoader 要求指定优化后 dex 文件存放的位置。 

PathClassLoader 的限制要更多一些,它只能加载已经安装到 Android 系统中的 apk 文件,也就是 /data/app 目录下的 apk 文件。其它位置的文件加载的时候都会出现 ClassNotFoundException. 例如:

代码如下:

PathClassLoader cl = new PathClassLoader(jarFile.toString(), "/data/app/" , ClassLoader.getSystemClassLoader()); 


由于 PathClassLoader 会去读取 /data/dalvik-cache 目录下的经过 Dalvik 优化过的 dex 文件,这个目录的 dex 文件是在安装 apk 包的时候 由 Dalvik 生成的。例如,如果包的名字是 xiaogang.test,Android 应用安装之后都保存在 /data/app 目 录下,即 /data/app/xiaogang.test-1.apk,那么 /data/dalvik-cache 目录下就会生成 data@app@xiaogang.test-1.apk@classes.dex 文件。在调用 PathClassLoader 时,它就 会按照这个规则去找 dex 文件,如果你指定的 apk 文件是 /sdcard/test.apk,它按照这个规则就会去读 /data /dalvik-cache/sdcard@test.apk@classes.dex 文件,显然这个文件不会存在,所 以PathClassLoader 会报错。 

在 Google 修正这个问题之前,我们要么就只能用 DexClassLoader,要么就只能用 PathClassLoader 加载已安装的 apk

接下来制作dex文件,用dx 命令生成 .dex 文件

1.dx 加入环境变量

dx路径   /sdk/android-sdk-macosx/tools:/Users/jianweiwang/Documents/dev/sdk/android-sdk-macosx/build-tools/22.0.1

用vim命令加入   vim ~/.bash_profile 

source 命令 生效 source  ~/.bash_profile 

2.执行命令

dx --dex --output ./TestClassLoader.dex ./TestClassLoader.class

但是出现错误:

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 TestDex.class

  参考:http://gaebolg.blog.163.com/blog/static/19826906820138544049440/

http://stackoverflow.com/questions/24662801/bad-class-file-magic-or-version

原因 我用javac 编译的class文件 java 环境是1.8

解决方法 :

用eclipse 导出个 1.6的class 继续执行命令  dx --dex --output ./TestDex.dex .

出现错误

UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dx.cf.iface.ParseException: class name (com/example/testactivity/TestDex) does not match path (com/example/TestDex.class)
	at com.android.dx.cf.direct.DirectClassFile.parse0(DirectClassFile.java:520)
	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.processDirectory(ClassPathOpener.java:229)
	at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:158)
	at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:229)
	at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:158)
	at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:229)
	at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:158)
	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 com/example/TestDex.class

  类文件夹不一致 

建立相应文件夹执行

com/example/testactivity/
执行dx命令 成功生成:TestDex.dex

 

posted on 2015-10-13 11:52  wjw334  阅读(2570)  评论(0编辑  收藏  举报

导航