google对java虚拟机进行了修改,只能运行将所有.class文件转为为一个.dex的文件,在Android的dalvik和ART虚拟机上无法直接运行.class文件,但是Google提供了将.class转为dex的工具 – dx
dx并没有配置到环境变量中,需要到对应目录下输入命令行.
首先随便编写一个简单的普通java代码,比如HelloWorld.java,因为没法看到图形化的界面,其中需要一条输出语句分辨程序是否有执行.
javac编译为HelloWorld.class或使用IDE运行一下生成.class文件.
在dx的目录打开cmd dx --dex --output=(输出路径) (.class文件路径)
比如: dx --dex --output=D:\Hello.dex HelloWorld.class
这时可能出现以下2个错误:
第一个:
PARSE ERROR: unsupported class file version 52.0 ...while parsing (class的绝对路径) 1 error; aborting |
version 52.0是指java8,AS都支持了java8了,并且dx的版本也是新版sdk最新的Platform tool,这个dx居然还不支持,和dx同路径的runtime.properties文件里面指定Runtime.Jvm=1.6,但是用1.7编译的.class是可以的,修改配置文件也无效,不是太清楚是怎么回事.
该错误可以在javac命令时使用指定版本:
javac -source 1.7 -target 1.7 (.class的绝对路径)
会有一个警告,不用理会即可
第二个:
PARSE ERROR: class name (Temp) does not match path (C:/Users/NessCurie/Desktop/HelloWorld.class) ...while parsing C:/Users/NessCurie/Desktop/HelloWorld.class 1 error; aborting |
这里在输入.class的路径时,直接从桌面上拖到cmd上输入了绝对路径,dx的.class文件不支持绝对路径,只能放到dx目录下,使用相对路径.
解决方式:放到dx目录里面就好了…
找到生成的Hello.dex文件,需要push手机中,没有root的手机有权限push进去的目录找了几个就只有/data/local/tmp,root了的手机push到任意目录即可.
这里以data/local/tmp为例:
adb push Hello.dex /data/local/tmp
adb shell
cd到push的dex文件的目录: cd /data/local/tmp
app_process的运行命令格式为:
app_process [vm-options] cmd-dir [options] start-class-name [main-options]
即:app_process VM选项 (路径名) (类名)
比如:app_process -Djava.class.path=Hello.dex /data/local/tmp HelloWorld
可以看到cmd输出了一句:HelloWorld,到这一步,就成功的在Android上运行了纯java文件.
修改helloworld为死循环一直输出helloworld,重复上面的步骤,运行Hello.dex.
再次打开一个cmd,adb shell后ps查看当前运行的进程,经过对比可以看到运行起来的程序进程为app_process.
PS
通过命令行启动的进程USER为shell,shell有比较高的权限的.
不过也只有通过命令行启动的情况才是shell,如果在应用中运行命令行启动外部的纯java程序的dex,启动的应用USER是和当前启动它的应用的USER一样的.
运行cmd的工具类可以使用Trinea的ShellUtils,具体可以查看: Trinea的ShellUtils介绍
使用ShellUtils在应用中启动java程序:
1 2 3 4 5 6 7 8 9 |
String s1 = "cd /data/local/tmp"; String s2 = "app_process -Djava.class.path=Temp.dex /data/local/tmp Temp"; final String[] arr = {s1, s2}; new Thread() { //死循环放在主线程会造成卡死,得放到子线程 @Override public void run() { ShellUtils.execCommand(arr, false); } }.start(); |
ps
可以看到USER和启动它的应用一样,这时候并没有很高的权限.
至此在Android中运行纯java程序的方法就介绍完了,从应用中启动目前还没想到比较好的用途,如果有想到可以一起交流交流. 不过从cmd中启动的方式因为权限比较高,所以还是可以做很多事情的,比如下一次要说的内容: 强行开启对应应用的辅助功能.