记录一下在生成dex文件时遇到三个问题及解决方法
1.创建临时目录
首先在project目录下创建一个临时目录,然后将项目修复完bug的代码及目录结构拷贝一份出来放到临时目录中,然后删除未做修改的代码文件。
2.编译class
在临时目录里打开Terminal 运行javac Xxx.java
将java文件编译为Xxx.class文件。
3.生成dex
使用dx.bat 生成dex文件,查看工程的buildToolsVersion版本,然后在sdk的build-tools目录中找到对应的版本,在Terminal中输入 :cd 对应的build-tools目录(例如:cd D:\Android\SDK\build-tools\29.0.2
),然后运行dx --dex --output upgrade.dex com/example/hotfix/Fixed.class
PS: upgrade.dex为生成dex路径可自行修改,com/.../Fixed.class为要编译的class文件路径,根据实际情况修改 ,回车。
4.出现的问题
输入:dx --dex --output=D:\Android\workspace\PluginDemo\to-be-fixed\com\example\hotfix\fix.dex com\example\hotfix\FixedBean.class
1.问题一
java.lang.UnsupportedClassVersionError: org/apache/lucene/store/Directory : Unsupported major.minor version 51.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Exception in thread "main"
问题原因:是因为电脑上有两个版本的jdk(自己装的一个,AS带的一个),编译.class是jdk版本与生成dex时需要的jdk版本不一致导致的,可在cmd窗口查看对应的jdk版本 java -version 、javac -version。
解决办法:修改环境变量中path的jdk的路径。
2.问题二
输入:dx --dex --output=D:\Android\workspace\PluginDemo\to-be-fixed\com\example\hotfix\fix.dex to-be-fixed\com\example\hotfix\FixedBean.class
UNEXPECTED TOP-LEVEL EXCEPTION:
java.lang.RuntimeException: com\example\hotfix\FixedBean.class: file not found
at com.android.dex.util.FileUtils.readFile(FileUtils.java:51)
at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:168)
at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:143)
at com.android.dx.command.dexer.Main.processOne(Main.java:678)
at com.android.dx.command.dexer.Main.processAllFiles(Main.java:575)
at com.android.dx.command.dexer.Main.runMonoDex(Main.java:310)
at com.android.dx.command.dexer.Main.runDx(Main.java:288)
at com.android.dx.command.dexer.Main.main(Main.java:244)
at com.android.dx.command.Main.main(Main.java:95)
1 error; aborting
问题原因:class输入路径导致。
解决办法:将to-be-fixed\com\example\hotfix\FixdBean.class
替换为com\example\hotfix\FixdBean.class
3.问题三
输入:dx --dex --output=fix.dex com\example\hotfix\FixdBean.class
PARSE ERROR:
class name (com/example/hotfix/FixedBean) does not match path (FixdBean.class)
...while parsing FixedBean.class
1 error; aborting
问题原因:还是因为class路径问题导致的。
解决办法:把com及子目录拷贝一份到build-tools对应的版本目录中,也就是和dx.bat同及目录下,再次运行就可以成功生成.dex文件了。