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.

PSPS

通过命令行启动的进程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();

psps

可以看到USER和启动它的应用一样,这时候并没有很高的权限.


至此在Android中运行纯java程序的方法就介绍完了,从应用中启动目前还没想到比较好的用途,如果有想到可以一起交流交流. 不过从cmd中启动的方式因为权限比较高,所以还是可以做很多事情的,比如下一次要说的内容: 强行开启对应应用的辅助功能.

更多相关文章

  1. Android高级开发第三讲--应用程序基础
  2. Android系统编译―Android.mk文件的简单介绍
  3. Android应用程序注册广播接收器(registerReceiver)的过程分析
  4. Android应用程序进程启动过程的源代码分析
  5. android 工程中重新生成gen文件夹或R.java 文件
  6. [转载]Android布局文件中命名空间的解析
  7. Android Layout布局文件里的android:layout_height等属性不起作

随机推荐

  1. 《Effieicntt Android Threading》 Chapt
  2. Webview实现android简单的浏览器实例代码
  3. 关于Android中的消息机制和异步
  4. Android 打造任意层级树形控件 考验你的
  5. 如何将Android应用发布到Google Play(Andr
  6. android缩放大图片加载
  7. android 判断横竖屏问题的详解
  8. Android 27+ 限制App所有未加密的http连
  9. Android实现伸缩弹力分布菜单效果
  10. Android(安卓)Lifecycle的一些感悟