NDK工具使用,JNI开发

来源:互联网 发布:守护进程 windows 编辑:程序博客网 时间:2024/06/04 18:55

小编最近遇到一个需求,寻思着用平常(Android)的解决方案去解决但是没找到,还好小编曾经的曾经学过C/C++,虽然很多都已经忘记,但是语言嘛,想再去学习就不那么难了。需求是:在你应用被卸载的完毕后,弹出一个网页,这种需求并不少见,但是仔细一推敲,本应用程序都已经被卸载了,随之进程也肯定被杀死了不在内存了,进程没了,怎么去实现弹出一个网页呢?于是救命稻草来了,JNI,使用java+c的模式来开发自己的应用程序,大家应该知道在C中,进程是可以自己fork出来的,因为在C中是没有GC机制的,需要手动去申请和释放内存,那么接下来就学学JNI吧。

NDK开发工具

NDK的理解

1.其实NDK就是一系列的工具的集合它提供了一系列的工具,帮助开发者去快速的开发C/C++的动态库,并且可以自动的将so和java应用一起打包成apk。帮助很大

2.NDK集成了交叉编译器,开发人员只需要简单的修改mk文件,就可以创建出so

3.NDK发布以后,官方也支持了java+c的这种模式

4.java的包都是可以进行反编译的,使用NDK我们可以将需要保密的应用逻辑使用C开发。这样提高了安全性。

接下来就使用NDK工具来进行JNI开发吧,这里使用eclipse(studio的方式暂时还没研究过,虽然小编早已经不用eclipse了)

===============================

首先你需要下载NDK并解压到一个文件夹下面:

1.打开eclipse下preference中android下的NDK,将NDK工具关联进来

2.右击工程,android tools下的 add Native suport

3.命名,xxxx-jni ,

4.会生成jni文件夹,将.cpp文件后缀改成.c,同时将android.mk中的.cpp,改成.c

5.为了支持更多平台,在jni文件夹中创建一个Application.mk,写入APP_ABI := all

6.右击 demo-jni.c 文件 选择properties,C/C++ 下的 path and symble 添加iclude文件夹

7.在本工程下的src下打开ndk-builde.cmd命令窗口(先配置环境变量,在path下配置ndk-builde.cmd目录),然后输入javah 包名.类名,在该目录下生成一个文件,该文件中有native方法的名字,拷贝方法名,然后将该文件添加到jni文件夹中,并在src中删除,然后在xxx-jni.c文件里粘贴上刚刚复制的方法名,在该方法中用C实现即可。

8.动态加载库文件

//生成的是动态的os文件  要动态的加载库文件static{    System.loadLibrary("demo-jni");}

JNI常见的几个错误

  • 找不到库 java.lang.UnsatisfiedLinkError: Couldn’t load calc-jn1:
  • 原因1 : 加载的库名不正确
  • 原因2 : 库的代码与运行平台的不符合,新建 Application.mk其中添所有支持平台的库的生成APP_ABI := all

  • 找不方法 java.lang.UnsatisfiedLinkError: Native method not found: com.itheima.resultfromc.MainActivity.resultFromC:(II)I

  • 原因1 : 本地方法名没按jni规范
  • 原因2 : 没有加载库

eg1:将java中的字符串传递到C中,进行逆向加密,然后到java中

这里写图片描述

char *rever_string(char *s){//传入的是指针变量,地址传递,将S中的元素 逆向排序  然后直接将S返回去//s是一个字符数组  s这个数组名就代表数组的首地址char *p = s;  //分成两句就是:char *p; p = &s;char *q = s;char temp = 0;//让q指向字符数组中 \0的位置while( *q != '\0'){    q++;  //q是char类型指针,加1,一次数值上 也是加1,一次往后面移动直到\0}q--;  //让q移动到\0前一个的位置上//交换p q的位置while(p < q){    temp = *p;    *p = *q;    *q = temp;    p++;  //前面的往后面移动    q--;  //后面的往前面移动}return s;}JNIEXPORT jstring JNICALL Java_com_example_jnidemo_MainActivity_code (JNIEnv *evn, jobject obj, jstring jstr){//加密  逆向加密//首先获取字符串的长度jstring len = (*evn)->GetStringLength(evn, jstr);char *ch = NULL;jstring jNewStr;//动态申请内存   字符指针<=>声明一个字符数组  c中字符数组要多申请一个字节来存储 \0,ch = (char *)malloc(len + 1);//将java传递过来的字符串jstr中的内容拷贝到C中的字符数组中(*evn)->GetStringUTFRegion(evn,jstr,0,len,ch);//将字符数组中的元素逆向排序   定义一个方法  返回值 是 char *, 传入的参数是 char *ch = rever_string(ch);jNewStr = (*evn)->NewStringUTF(evn,ch);//申请了内存空间一定要自己手动释放掉free(ch);return jNewStr;}

回到正题,上面说哪个需求,接下来就是实现的代码了,直接上:

这里写图片描述

希望大家多多回馈项目中使用JNI开发的案例,多多交流多多学习。Thanks

1 0