Android上app_process启动java进程
2016-11-14 20:45
1156 查看
Java程序是跨平台的,由JVM虚拟机执行字节码。Android应用程序开发也是Java,但是都是运行在Context环境下的。独立的Java程序能够在Android上独立运行?
这里不介绍Android启动过程中,app_process从哪个进程fork处理,也不介绍app_process启动App的过程。仅介绍app_process启动纯Java程序的相关知识。
Android对Java虚拟机做了修改,即使用自己的dalvik虚拟机(后来的ART)。因此,.class的字节码在Dalvik虚拟机上是不能运行的。Android Platform tool为我们提供了生成Android上可执行jar(Dex)工具:dx。编译命令如下:
app_process运行参数居然没有help,万恶的开发者。这块要么查资料,要么看源码。从网上找的对参数解释如下:
将我们前面编译得到的dex(jar)文件push到/data/local/tmp文件夹下,构建app_process运行参数:
切换/data/local/tmp目录下运行,HelloWorld就成功运行啦!
为了能够查看app_process启动的Java程序的进程信息,希望demo程序不立马执行结束,以便能够通过ps查看进程信息。修改上面的demo程序,变成死循环让程序持久存活,并先后启动两个这样的Java程序。
通过上面进程信息可以看到,每次Java程序运行时,系统都会给其分配一个pid,并且进程名都是app_process。(至于为什么要这么命名,不清楚。。。)
通过追踪ppid,还能发现启动的java进程源自何处,即怎么fork出来的,即:/init–>/sbin/adbd–>/system/bin/sh–>app_process(Java进程),也就是说,启动的Java进程是从/system/bin/sh(shell)fork出来的。
知道了相应的pid,就可以通过pid查看进程信息,对应的shell命令为:cat /proc/[pid]/status.
通过上面信息可以看到,app_process启动的Java程序运行的uid是和pid是2000,也就是shell 的Uid,所以app_process启动的Java程序拥有shell级别的权限,下面就此来做个验证。
和前面demo一样编译到Android下运行,查看结果,发现可以正常输出,说明app_process启动的Java程序的确具有shell级别的权限(其实其Uid就是shell)。
总结: 上面说明了app_process启动Java的相关知识,至于有啥重要用途,后续会陆续给出。
这里不介绍Android启动过程中,app_process从哪个进程fork处理,也不介绍app_process启动App的过程。仅介绍app_process启动纯Java程序的相关知识。
一、HelloWorld示例
1. 源程序
编写一个hellworld 的Java程序,并且编译成.class文件,简单得没啥可说的。public class Helloworld { public static void main(String[]args){ System.out.println("Hello, I am started by app_process!"); } }
Android对Java虚拟机做了修改,即使用自己的dalvik虚拟机(后来的ART)。因此,.class的字节码在Dalvik虚拟机上是不能运行的。Android Platform tool为我们提供了生成Android上可执行jar(Dex)工具:dx。编译命令如下:
//编译,这里主要是Platform tool上用的是Java 7,所以显式指定1.7 javac -source 1.7 -target 1.7 C:\Users\Venscor\Desktop\app_process\dump.java //生成dex,当然生成jar在Android上也是可执行的 dx --dex --output=C:\Users\Venscor\Desktop\app_process\Hellworld.dex Helloworld.class
2. 运行
app_process参数格式如下:app_process [vm-options] cmd-dir [options] start-class-name [main-options]
app_process运行参数居然没有help,万恶的开发者。这块要么查资料,要么看源码。从网上找的对参数解释如下:
vm-options – VM 选项 cmd-dir –父目录 (/system/bin) options –运行的参数 : –zygote –start-system-server –application (api>=14) –nice-name=nice_proc_name (api>=14) start-class-name –包含main方法的主类 (com.android.commands.am.Am) main-options –启动时候传递到main方法中的参数
将我们前面编译得到的dex(jar)文件push到/data/local/tmp文件夹下,构建app_process运行参数:
app_process -Djava.class.path=Helloworld.dex /data/local/tmp Helloworld
切换/data/local/tmp目录下运行,HelloWorld就成功运行啦!
二、被启动的Java的Pid, Uid与权限
上面展示了使用app_process在Android启动独立的Java进程的Demo。那么,被启动的Java程序作为一个独立的进程,其从何处fork而来,Uid为多少,对应什么级别权限就是下面要解决的问题。为了能够查看app_process启动的Java程序的进程信息,希望demo程序不立马执行结束,以便能够通过ps查看进程信息。修改上面的demo程序,变成死循环让程序持久存活,并先后启动两个这样的Java程序。
通过上面进程信息可以看到,每次Java程序运行时,系统都会给其分配一个pid,并且进程名都是app_process。(至于为什么要这么命名,不清楚。。。)
通过追踪ppid,还能发现启动的java进程源自何处,即怎么fork出来的,即:/init–>/sbin/adbd–>/system/bin/sh–>app_process(Java进程),也就是说,启动的Java进程是从/system/bin/sh(shell)fork出来的。
知道了相应的pid,就可以通过pid查看进程信息,对应的shell命令为:cat /proc/[pid]/status.
通过上面信息可以看到,app_process启动的Java程序运行的uid是和pid是2000,也就是shell 的Uid,所以app_process启动的Java程序拥有shell级别的权限,下面就此来做个验证。
三、启动的Java程序拥有的权限及Uid
adb shell中,dumpsys activity命令是查看Activity栈信息的,只有shell权限(可能有shell权限也不行,必须Uid为shell,没有去看)才能调用。所以可以通过这个来验证启动的Java程序是否真的运行于shell的Uid下,测试源代码如下:import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class dump { public static void main(String[]args){ String cmd="dumpsys activity"; System.out.println("Hello, I am started by app_process!"); try { Process p=Runtime.getRuntime().exec(cmd); BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream())); String readLine=br.readLine(); while(readLine!=null){ System.out.println(readLine); readLine=br.readLine(); } if(br!=null){ br.close(); } p.destroy(); p=null; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
和前面demo一样编译到Android下运行,查看结果,发现可以正常输出,说明app_process启动的Java程序的确具有shell级别的权限(其实其Uid就是shell)。
总结: 上面说明了app_process启动Java的相关知识,至于有啥重要用途,后续会陆续给出。
相关文章推荐
- android java代码的启动:app_process
- android java代码的启动:app_process
- android java代码的启动:app_process
- android java代码的启动:app_process
- Android app启动一个新进程流程
- 在Java App中启动进程
- Android:adb通过app_process调用java类报错-java.lang.ClassNotFoundException
- 【Android】 01. APP 进程启动和 ActivityThread 的关系
- 解析android framework下利用app_process来调用java写的命令及示例
- 使用AS编译时,报Error:Execution failed for task ':app:transformClassesWithDexForDebug'. > com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concur
- Error:Execution failed for task ':app:transformClassesWithDexForDebug'. > com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.Exec
- AndroidStudio Unable to start the daemon process(无法启动Gradle守护进程)
- android coreApp=true属性以及android4.2及以下多用户进程启动的说明
- Java启动子进程,子进程又启动孙进程后,Java在InputStream inputStream = process.getInputStream();中读取时,何时会返回null?
- android启动:app_process实现恢复出厂设置可恢复的apk预置
- android:process用于在新进程中启动Activity
- Android应用程序(app)进程启动过程的源代码分析
- [Android] 解析android framework下利用app_process来调用java写的命令及示例
- android coreApp=true属性以及android4.2及以下多用户进程启动的说明
- Android开发 APP进程启动原理