正文
1.
编写基本的Java文件并编译为 .class 文件。
2.
将 .class 文件转为 .dex 文件。
3.
将转好的 dex文件 放入创建好的Android工程内并在启动时将其写入本地。
4.
加载解压后的 .dex 文件中的类,并调用其方法进行测试。
Note:
在阅读本节之前最好先了解一下
类加载器的双亲委派原则
、
DexClassLoader的使用
以及
反射
的知识点。
编写基本的Java文件并编译为.class文件
首先我们在一个工程目录下开始创建并编写我们的Java文件,你可能会选择各种IDE来做这件事,但我在这里劝你不要这么做,因为有坑在等你。等把基本流程搞清楚可以再选择更进阶的方法。这里我们可以选择文本编辑器比如EditPlus来对Java文件进行编辑。
新建一个Java文件,并命名为:
ClassStudent.java
,并在java文件内键入以下代码:
public class ClassStudent {
private String name;
public ClassStudent() {}
public void setName(String name) {
this.name = name;
}
public String getName(){
return this.name + ".Mr";
}
}
Note:
这里要注意,不要对类添加包名,因为在后期对class文件处理时会遇到问题,具体问题会稍后说明。上面的
getName
方法在返回时对
this.name
属性添加了一段字符串,这里请注意,后面会用到。
在文件创建好之后,对Java文件进行编译:
将.class文件转为.dex文件
好,现在我们使用class文件生成对应的dex文件。生成dex文件所需要的工具为dx,dx工具位于sdk的
build-tools
文件夹内,如下图所示:
Tips:
为了方便使用,建议将dx的路径添加到环境变量中。如果对dx工具不熟悉的,可以在终端中输入
dx –help
以获取帮助。
dx工具的基本用法是:
dx --dex [--output=file>] [file>.class | file>.{zip,jar,apk} | directory>]
Tips:
刚开始自己摸索的时候,就没有仔细看命令,导致后面两个参数的顺序颠倒了,搞出了一些让人疑惑难解的问题,最后又不得不去找dx工具的源码调试,最后才发现自己的问题在哪。如果有对dx工具感兴趣的,可以对dx的包进行反编译或者获取dx的相关源代码进行了解。dx.lib文件位于dx.bat的下级目录lib文件夹中,可以使用JD-GUI工具对其进行查看或导出。如果需要获取源代码的,请使用以下命令进行克隆:
Git clone https://android.googlesource.com/platform/dalvik
我们使用以下命令生成dex文件:
dx --dex --output=user.dex ClassStudent.class
这里我为了防止出错,提前在当前目录下新建好了 user.dex 文件。上述命令依赖编译.class文件的JDK版本,如果使用的是JDK8编译的class会提示以下问题:
PARSE ERROR:unsupported class file version 52.0
...while parsing ClassStudent.class
1 error; aborting
这里的
52.0
意味着class文件不被支持,需要使用JDK8以下的版本进行编译,但是dx所需的环境还是需要为JDK8的,这里我编译class文件使用的是JDK7,请注意。
上面我们提到了为什么先不要在ClassStudent中使用包名,因为在执行dx的时候会报以下异常,这是因为以下第二项条件没有通过,该代码位于
com.Android.dx.cf.direct.DirectClassFile
文件内:
运行截图如下所示:
好了,到此为止我们的目录应该如下:
写入dex到本地磁盘
接下来将生成好的user.dex文件放入Android工程的res\raw文件夹下:
在系统启动时将其写入到磁盘,这里不再贴出具体的写入代码,项目的MainActivity中包含了此部分代码。