使用jni接口完成android本地程序的运行
接下来,想把程序打包到一个基于java的apk中,安装的时候直接将程序复制到和apk相同的目录下,然后由java程序使用exec调用这个本地程序。实验证明,由于权限问题,不可行!后来又想将程序通过apk直接复制到SD卡上,但是通过查看android的源代码发现,SD卡被mount的时候是指定了noexec标志的,也就是说SD卡上的程序无法执行(这是有道理的,因为如果sd卡的程序可以执行的话,随便一个溢出漏洞就可能危害系统...再说,sd卡耗电,又不稳定)...于是,没有办法了!难道在android上开发程序必须用java吗?其实不是这样的!虽然接口是java,但是java明确规定了又jni接口可以调用本地程序的,如此看来,既然java对于android是被信任的,那么使用java的jni调用的本地程序也是被信任的(虽然java虚拟机并不管理它,但是它确实没有任何管理者监管啊),于是就想办法将要执行的本地程序封装成一个so(动态库),然后用java的loadlibrary执行之。
以ABC c语言编写的程序为例,下面的步骤搞定了它,这里仅仅用java SE作为例子,没有使用android的sdk/ndk,然而其工作原理是一样:
1.首先写一个java程序,很简单的:Test.java
class Test
{
public native void jni_main();
static {
System.loadLibrary("abc");
}
public static void main(String[] args) {
new Test().jni_main();
}
}
2.生成头文件:
javah Test
生成Test.h
3.将Test.h复制到ABC的源码目录下
4.想办法将abc编译成libabcd.so(其实ABC本来在linux平台被编译成一个elf可执行文件的,这里要把它编译成so,用于java程序的jni接口加载)
4.1.修改abc.c,如下:
//int main(int argc, char* argv[]) { //原来的main函数
JNIEXPORT void JNICALL Java_TestABC_Wrapper_1main (JNIEnv *env, jobject obj) { //修改后的jni接口调用的main函数
...
}
4.2.编写Makefile文件:
#开始
CC := droid-gcc
LD := droid-ld
DEFS = ...#复制原来的Makefile的该字段
LIBS = ...#复制原来的Makefile的该字段
CFLAGS := ...(复制原来Makefile的该CFLAGS) -I...#复制和android相关的头文件的路径
LDFLAGS := -shared -fpic
SOURCE := $(wildcard *.c)
OBJS := $(patsubst %.c,%.o,$(SOURCE))
TARGET_LIB := libabc.so
all:$(OBJS)
$(LD) $(LDFLAGS) -o $(TARGET_LIB) $(OBJS) $(LIBS)
%.o:%.c
$(CC) -c $(CFLAGS) $< -o $*.o
*.o -rf
#结束
5.编译,执行make,最终生成一个so,然后运行java Test,结果是abc被运行啦!
PS:我认为,google的android仅仅用java作为其主流开发语言,这是不妥的,这样就使得很多厂商望而却步,很多做c的人望而却步,本来android的用户就没有symbian的多,现在由于这个原因,更使得它只能在众多hacker圈子里打转,一般的手机用户是不懂什么linux的,也不关心什么root权限,因此很多hacker方略对于一般的用户是没有意义的,他们关心的最终的体验,因此很多的任务不得不压在开发者身上,开发者越多就意味着潜在用户越多,symbian走的就是这条路线,palm当初也许就是因为没有走这个路线而失败的。因此,不管怎么多,平台提供者不应该限制开发者,开放的越多,应用就会越多,众口难调的用户才会易于伺候。
本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1271175

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
使用jni接口完成android本地程序的运行--具体的操作
虽然上一篇文章《使用jni接口完成android本地程序的运行》讲述了一些理论上的知识,但是如何具体操作呢?要知道android的java虚拟机与标准的jvm是不一致的,因此肯定会遇到具体操作的问题。实际上,具体操作也不难,只要按照android文档的介绍按部操作即可: 1.在apps目录下拷贝一个最简单的例子,比如hello-jni作为模板,命名为你的应用的名称,然后删除其下的和hello-jni相关的内容; 2.将需要编译的源代码树拷贝到jni目录之下; 3.jni目录下的Android.mk文件内容如下: LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_CFLAGS := ...#拷贝所有原始Makefile中的CFLAGS/CPPFLAGS/等等一切命令行标志,包括预编译宏的定义 LOCAL_LDLIBS := ...#拷贝所有的链接时用到的动态库路径,动态库,静态库(-L,-l) LOCAL_MODULE := ...#最终的供java调用的so名称,省略了lib和.so的 LOCAL_SRC_FILES ...
-
下一篇
android中webView加载H5,JS不能调用问题的解决
使用了html5 页面,使用webView加载后发现 超链接的锚点不可以用 为webView设置下面两句就好了: mWebView.getSettings().setDomStorageEnabled(true); mWebView.getSettings().setDatabaseEnabled(true); 标签: Android, webview 本文转自 netcorner 博客园博客,原文链接:http://www.cnblogs.com/netcorner/p/8207212.html ,如需转载请自行联系原作者
相关文章
文章评论
共有0条评论来说两句吧...