NDK相关资料

来源:互联网 发布:mac快速进入屏保 编辑:程序博客网 时间:2024/06/05 11:43

前言:内容是记录学习测试NDK时的笔记,想学习的朋友可以参考下,可能内容并不完善,因为当时只是摘要记录而已,后面涉及到这块会完善补充。

重点内容
NDK学习:
Android NDK开发是学习怎样使用C与java共同开发Android应用层的技术,有了NDK技术后,你就可以开发出只用java不能开发的一些特殊项目,因为java不能,而C可以。学习了NDK技术后,就有基础学习Android的中间件开发,因为中间件大量使用了NDK技术。

全过程:
1. 把C函数在so动态库中写成对应的函数表示
2. 在java部分,首先加载动态库,然后声明动态库中相应的函数,最后java实例对象调用该函数

public class HelloWorld{   //本地函数(即声明动态库中show函数)   private native void show();   public static void main(String[] args){       System.loadLibrary("wgr");//加载动态库(其中写so动态库名称的中间部分)       new HelloWorld().show();//调用函数   }}

基础小结:
1. java直接去调用C函数是调用不到的,必须把C做成 .so 结尾的动态库才可以被调用
2. 动态库名称的写法 libwgr.so,其中lib .so 固定写法,而wgr可以改变
3. NDK技术的使用绝大多数都是java调用C
4. so文件可以理解为java与C语言沟通的桥梁,把C部分做成so文件后,那么C部分文件即使删除了也可以运行成功,因为java只能运行so文件中的内容
5. 在java中的权限修饰符,如public、private等对C完全不影响,C不需要理会
6. 如果是类对象调用本地函数,则thiz指”类对象”;如果类名.静态方法的方式调用本地函数,则jc指”类.class”文件

DNK环境搭建:
1. DNK运行环境:将下载的android-ndk-r10c-windows-x86_64.exe可执行文件双击运行,会自动在当前目录下解压到对应的文件夹
2. 添加jar:将“com.android.ide.eclipse.ndk_23.0.2.1259578.jar”复制到eclipse工具 “F:\Android\adt-bundle-windows-x86_64-20140702\eclipse\plugins\com.android.ide.eclipse.ndk_23.0.2.1259578.jar”
3. 在eclipse工具中添加DNK环境:选择菜单栏上的[Window->Perferences->Android->NDK]设置 NDK Loaction 为F:\Android\android-ndk-r10d;
4. 在Window系统中添加DNK环境:添加环境变量 NDK_ROOT 为: D:\Android\android-ndk-r10d 在环境变量 PATH 下追加 :%NDK_ROOT%;

NDK与JNI区别:
JNI表示Java Native Inteface,是Java中定义的一种用于连接Java和C/C++接口的一种实现方式。
AndroidNDK是一套工具,允许Android应用开发者嵌入从C、C++源代码文件编译来的本地机器代码到各自的应用软件包中,并通过JNI进行访问
小结:JNI是java连接C的桥梁,是一种可实现的方式;NDK是允许java和c相互沟通的环境

Cygwin简介:
cygwin是一个在windows平台上运行的unix模拟环境,它对于学习unix/linux操作环境,或者从unix到windows的应用程序移植,非常有用。通过它,就可以在不安装linux的情况下使用NDK来编译C、C++代码了。
注意:
1. Cygwin安装切记去官网上下载最新的可执行文件,在网络上下载的其他可执行文件可能会出问题
2. 安装时切记选择需要的编译工具链和GNU,不然打开Cygwin.bat时会一闪而

生成so动态库命令:(进入NDK空间的某个项目下,执行如下命令,自动生成so文件,只需在eclipse中刷新项目即可看到生成的so文件)
1. 运行 cygwin中Cygwin.bat
2. 进入项目文件夹
3. 运行命令$ndk/ndk build
(没有测试)

重点:(运行项目时)
1. 由于eclipse不能很好的支持C语言的编写,所以最好把写好的C复制到jni文件夹中
2. 当所有文件都准备好后,记得在运行钱添加一下本地支持:Add Native Support
3. 在运行之前,libs中存放so动态库的文件夹是空的,只有运行后才有自动补上内容
4. 在当前生成so动态库的项目中不可以删除jni等文件夹,会报错;(我们可以把运行后生成的so动态库拷贝到别的项目中使用)
5. Ctrl+B编译生成动态库
6. 在eclipse中编译C时,如果报错可以切换到C/C++视图,然后找到错误提示的地方,把错误全部删除即可(工具问题)
7. 打印输出的tag是LOGI中的”native-activity”位置的内容
这里写图片描述
这里写图片描述

java于C的传值和返回值原理:
java与C相互传值(基本数据类型)
1. java传参给C函数:首先C函数使用jni类型接收,然后把jni类型转换成C类型
2. C函数返回值返回给java:首先C类型转换成jni类型,然后把jni类型作为返回值返回给java
java传值到C(引用数据类型、String)
方式一:

void Java_com_mz_act_MainActivity_say(JNIEnv *env,jobject thiz,jstring word){   const char* p = (*env)->GetStringUTFChars(env,word,NULL);   LOGI("p=%s\n",p);   (*env)->ReleaseStringUTFChars(env,word,p);//回收}

方式二:

void Java_com_mz_act_MainActivity_say(JNIEnv *env,jobject thiz,jstring word){   int len = (*env)->GetStringLength(env,word);//得到字符串长度   char str[len];//创建字符串数组   (*env)->GetStringUTFRegion(env,word,0,len,str);   LOGI("c:str=%s\n",str);}

C返回值到java中:

/** * 返回c的字符串 */jstring Java_com_example_myhellojni_MainActivity_stringFromJNI(JNIEnv *env, jobject thiz) {    return (*env)->NewStringUTF(env, "伟才正在学习jni技术");}

小结:貌似在c中返回值到java中比较容易,不需要处理太多,而java中把值当作参数传入到c中,处理的步骤要多些,相对复杂一些。

关于C和JAVA知识:
1. 越是接近人的语言就越是高级语言,如JAVA,JAVA的最最底层也是用C来实现的,在操作系统上JAVA和C的互调通过JVM来实现,JVM就是一个函数库,里面封装C的函数,同时JVM理解Java字节码,所以能够充当中介角色。其中JNI技术就是针对中介指定的一套约束,从而保证Java和本地代码之间的沟通顺畅。
2. Java的垃圾回收机制不用处理,因为Java通过JVM调用了C函数,C中就有垃圾回收函数,单独的C零件是不可以进行垃圾回收的,C零件组成的函数可以进行垃圾回收
3. 在Android中,JAVA和C互调的中介就是NDK,JNI就是其中的约束,让调用更加方面顺畅
4. 越是接近机器的语言就是低级语言(机器语言),如C相对来说就是机器语言,机器语言的发展其实就是从最初的机器只认识的0、1开始组合,发展到汇编语言,汇编语言就是把0、1的各种组合通过助记符来表示,然后汇编语言再发展就是C语言,C语言只是一些零零散散的语言零件,后来C语言封装成函数就变成C++,C++相对C来说就充当了对象的作用。但是C++相对于Java来说还是很小儿科的,后来为了实现网站的需求就又发展了,变成了.NetAsp技术(C#),这个技术和JavaEE都可以开发网站。
5. object-c语言是集几个语言于一体组合而成的

以上就是全部内容,大家可以自个去试试,喜欢的朋友可以加个关注,以后有好的文章可以及时查阅讨论,有什么问题也可以留言,或者在微信公众号“技术帮团队”上找我们。

0 0
原创粉丝点击