NDK相关资料

前言:内容是记录学习测试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语言是集几个语言于一体组合而成的

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值