NDK工具使用,JNI开发
2016-06-07 23:52
295 查看
博客转移到个人站点:http://www.wangchengmeng.club/2018/02/04/NDK%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8%EF%BC%8CJNI%E5%BC%80%E5%8F%91/
欢迎来吐槽
小编最近遇到一个需求,寻思着用平常(Android)的解决方案去解决但是没找到,还好小编曾经的曾经学过C/C++,虽然很多都已经忘记,但是语言嘛,想再去学习就不那么难了。需求是:在你应用被卸载的完毕后,弹出一个网页,这种需求并不少见,但是仔细一推敲,本应用程序都已经被卸载了,随之进程也肯定被杀死了不在内存了,进程没了,怎么去实现弹出一个网页呢?于是救命稻草来了,JNI,使用java+c的模式来开发自己的应用程序,大家应该知道在C中,进程是可以自己fork出来的,因为在C中是没有GC机制的,需要手动去申请和释放内存,那么接下来就学学JNI吧。
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.动态加载库文件
原因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中
回到正题,上面说哪个需求,接下来就是实现的代码了,直接上:
希望大家多多回馈项目中使用JNI开发的案例,多多交流多多学习。Thanks
欢迎来吐槽
小编最近遇到一个需求,寻思着用平常(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
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题