Android通过java虚拟机实现运行每个app,不过Android的应用程序都是运行在Context上下文环境中的,从没在Android应用的代码中看到main方法,那普通的java程序如何在Android中运行.

google对java虚拟机进行了修改,只能运行将所有.class文件转为为一个.dex的文件,在Android的dalvik和ART虚拟机上无法直接运行.class文件,但是Google提供了将.class转为dex的工具 – dx

  • 老版本的sdk存放在SDK\platform-tools
  • 新的sdk存放在SDK\build-toolsx\xx.xx(版本号)

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.class1 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程序:

123456789
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中启动的方式因为权限比较高,所以还是可以做很多事情的,比如下一次要说的内容: 强行开启对应应用的辅助功能.

更多相关文章

  1. android动态加载(二)
  2. android framework 启动流程
  3. 使用jQuery Mobile和Phone Gap开发Android应用程序
  4. Android应用程序进程启动过程的源代码分析
  5. 爱奇艺Android移动客户端app瘦身经验
  6. Android系统编译―Android.mk文件的简单介绍
  7. Android之Adapter用法总结
  8. Android应用程序进程启动过程的源代码分析
  9. android AIDL服务

随机推荐

  1. android将ROM改为默认开启调试模式和未知
  2. Retrofit 2.0 使用教程
  3. 2016.4.25
  4. android XML转义字符
  5. MAC Android(安卓)Studio使用无线调试
  6. android-ProgressBar
  7. Android实现沉浸式状态栏的那些坑
  8. Android中使用MediaCodec硬件解码,高效率
  9. Android调用系统图库获取图片
  10. Android(安卓)5.0 SystemUI