天天看点

使用jni接口完成android本地程序的运行

最近在开发android相关的程序。可惜啊,android的开发接口都是基于java的,作为一个c开发者,于是我想开发一个c程序,然后想法root掉那个手机,然后使用adb工具将程序拷贝到手机里就可以运行了...想法很好,但是有两个问题,第一,靠点击根本无法运行本地程序;第二,如果程序发布,难道能指望用户将手机寄过来然后帮他们root吗?于是这个方法直接pass掉了。

     接下来,想把程序打包到一个基于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