[Android] 解析android framework下利用app_process来调用java写的命令及示例
reference to :http://bbs.9ria.com/thread-253058-1-1.html
在android SDK的framework/base/cmds目录下了,有不少目录,这些目的最终都是build出一个bin文件,再存放到/system/bin目 录下,对于C/CPP写的命令,我们还是比较好理解的,都有一个main函数作为入口,但是在cmds目录下还有一些原生代码是java的,比如 input、settings,那么这种类型的命令是怎么实现的呢?
笔者研习了原生的命令实现,写了一个demo,抛砖引玉吧!暂时叫strong吧!我们都知道java写的文件最后都是编译成了class文
件,java类里面也有很多接口,在android平台上cmds目录下的各模块的java文件都实现了一个共同的方法,还是叫main(),真是情有独
钟啊!当然从技术角度看叫其他名字也是可以的。那我们就简单实现以下这个class吧!如下:
java代码
public final class strongcmd {
static final String TAG = "strong";
static String[] mArgs;
int mNextArg;
public static void main(String[] args) {
printUsage();
System.err.println("Wellcom strong test function!!");
try {
new strongcmd().run();
} catch (Exception e) {
System.err.println("Unable to run settings command");
}
}
public void run() {
try {
System.err.println("Now strong run() again");
} catch (Exception e) {
System.err.println("Now strong run() Exception");
}
}
private static void printUsage() {
System.err.println("usage: strong -a -b -h");
System.err.println("'a' is for add");
System.err.println("-h for help");
}
}
写好Android.mk,编译好这个文件,会生成strong.jar包,包含这个class。那么,又怎么跟命令挂钩呢?先看看Android.mk,如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_MODULE := strong
LOCAL_MODULE_TAGS := optional
include $(BUILD_JAVA_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := strong
LOCAL_SRC_FILES := pre_strong
LOCAL_MODULE_CLASS := EXECUTABLES
LOCAL_MODULE_TAGS := optional
include $(BUILD_PREBUILT)
上一部分是BUILD_JAVA_LIBRARY,关键在下面,利用的是BUILD_PREBUILT,添加一个预编译好的应用程序,我们叫pre_strong,它有可执行的权限,看看它的具体实现吧!
base=/system
export CLASSPATH=$base/framework/strong.jar
exec app_process $base/bin com.android.commands.strong.strongcmd "$@"
首先还是设置好这个java lib的路径,如何再调用app_process来执行,主要是把这个类名要给对,app_process其实也是个命令。在app_process里 面,还是一样利用JNI技术,在java ENV里面查找传给app_process的class,找到这个class后再去找main函数接口的field,然后再call这个main接口,这 样就call到java里面去了。
下面简要看看app_process的关键代码吧!
virtual void onVmCreated(JNIEnv*env) {
if (mClassName == NULL) {
return; // Zygote. Nothing to do here.
}
/*
* This is a little awkward because the JNI FindClass call uses the
* class loader associated with the native method we're executing in.
* If called in onStarted (from RuntimeInit.finishInit because we're
* launching "am", for example), FindClass would see that we're calling
* from a boot class' native method, and so wouldn't look for the class
* we're trying to look up in CLASSPATH. Unfortunately it needs to,
* because the "am" classes are not boot classes.
*
* The easiest fix is to call FindClass here, early on before we start
* executing boot class Java code and thereby deny ourselves access to
* non-boot classes.
*/
char*slashClassName = toSlashClassName(mClassName);
mClass = env -> FindClass(slashClassName);
if (mClass == NULL) {
ALOGE("ERROR: could not find class '%s'\n", mClassName);
}
free(slashClassName);
mClass = reinterpret_cast(env -> NewGlobalRef(mClass));
}
virtual void onStarted() {
sp proc = ProcessState::self ();
ALOGV("App process: starting thread pool.\n");
proc -> startThreadPool();
AndroidRuntime * ar = AndroidRuntime::getRuntime ();
ar -> callMain(mClassName, mClass, mArgC, mArgV);
IPCThreadState::self () -> stopProcess();
}
className) {
// Remainder of args get passed to startup class main()
runtime.mClassName = className;
runtime.mArgC = argc - i;
runtime.mArgV = argv + i;
runtime.start("com.android.internal.os.RuntimeInit",
application ? "application" : "tool");
}
Android平台提供的app_process,还是相当不错的,比较实用,利用好app_process还是可以写成很多供我们自己开发、测试、定制一些特殊的程序,给开发带来了很大的便利。
[Android] 解析android framework下利用app_process来调用java写的命令及示例的更多相关文章
- 解析android framework下利用app_process来调用java写的命令及示例
解析android framework下利用app_process来调用java写的命令及示例 在android SDK的framework/base/cmds目录下了,有不少目录,这些目的最终都是b ...
- android源码framework下添加新资源的方法
编译带有资源的jar包,需要更改frameworks层,方法如下: 一.增加png类型的图片资源 1.将appupdate模块所有用到的png格式图片拷贝到framework/base/core/re ...
- TensorFlow下利用MNIST训练模型识别手写数字
本文将参考TensorFlow中文社区官方文档使用mnist数据集训练一个多层卷积神经网络(LeNet5网络),并利用所训练的模型识别自己手写数字. 训练MNIST数据集,并保存训练模型 # Pyth ...
- CentOS下利用sshpass不用手动输入密码远程执行命令
在测试的时候要同时操作多台机器,每次都要挨个去执行几乎相同的命令或者修改一些设置,这样很影响工作效率也很烦,所以就想写一个脚本,远程自动去做这些操作.远程执行命令很简单,但是不能在执行命令加上命 ...
- Android在使用WebView时,通过Javascript调用JAVA函数
webView = (WebView) findViewById(R.id.article_webview); //WebView启用Javascript脚本运行 webView.getSetting ...
- 使用C#利用cmd来调用java jar包获取其中的数据
其实也很简单,就是在C#中构建一个Process,启动jar包,并且给jar包传递参数 因为我并没有怎么学过JAVA,所以只写了个很小的Demo,就是根据传入的参数获取对应的数据 以下是JAVA De ...
- Unity调用Android的两个方式:其一、调用jar包
unity在Android端开发的时候,免不了要调用Java:Unity可以通过两种方式来调用Android:一是调用jar.二是调用aar. 这篇文章主要讲解怎么从无到有的生成一个jar包,然后un ...
- Unity调用Android的两种方式:其一、调用jar包
unity在Android端开发的时候,免不了要调用Java:Unity可以通过两种方式来调用Android:一是调用jar.二是调用aar. 这篇文章主要讲解怎么从无到有的生成一个jar包,然后un ...
- 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)
1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...
随机推荐
- ajax如何返回多个值
应用场景: 在前端有个ajax请求到后端后,需要返回多个变量的值,在这里使用的是Json格式作为值传递,使用eval函数来解析Json格式. 要传递的值data: var data = " ...
- Spotlight on oracle
Spotlight on Oracle 能让你迅速发现任何性能瓶颈,无论是实时还是历史查询.Spotlight 能鉴别和诊断几千种性能问题,无论是特定用户问题.集中资源SQL事务. I/O瓶颈.锁定等 ...
- 第2月第4天 injection plugin for xcode
http://www.cocoachina.com/ios/20140530/8623.html http://www.jianshu.com/p/27be46d5e5d4
- js时间格式化(yy年MM月dd日 hh:mm)
//时间格式化 Date.prototype.format = function (format) { var o = { "M+": this.getMonth() + 1, / ...
- XML文件数据操作
#region XML序列化文件和反序列化 /// <summary> /// 通用类的保存函数,可以将已经声明过可序列化的类以文件方式保存起来. /// 保存格式分为 XML明文式和 二 ...
- telnet: connect to address 127.0.0.1: Connection refused
telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式.它为用户提供了在本地计算机上完成远程主机工作的能力.在终端使用者的电脑上使用telnet程序,用它连接 ...
- func_num_args, func_get_arg, func_get-args 的区别与用法
func_num_args 返回传递给函数的参数个数 <?php header("Content-Type: text/html; charset=UTF-8"); func ...
- cacti错误
cacti 错误:CMDPHP: Poller[0] ERROR 解决方案: 找到错误表 desc 表名: 修复此表 mysqlcheck -A -o -r -p -u用户名
- 修改apache上传文件大小限制
PHP上传文件大小限制解决方法: 第一: 在php.ini里面查看如下行: upload_max_filesize = 8M post_max_size = 10M memory_limi ...
- ASP.NET 页生命周期概述
ASP.NET 页生命周期概述 Visual Studio 2005 ASP.NET 页运行时,此页将经历一个生命周期,在生命周期中将执行一系列处理步骤.这些步骤包括初始化.实例化控件.还原和维 ...