安卓篱笆
标题:
Android安卓JNI/NDK开发(一)
[打印本页]
作者:
GuiTarvvm2098
时间:
2017-11-30 04:04
标题:
Android安卓JNI/NDK开发(一)
[attach]401[/attach]
eclipse下使用JNI
1. 在项目根目录下创建jni文件夹 ,与src同级
2. 在jni文件中创建一个c文件后缀名为
.c
/****这就是创建一个jni的native方法,用来调用c函数****/
3. 在java代码中,创建一个本地方法,名字随意,如helloFromc()方法,没有方法体,连大括号也不要。
但是必须加关键字native,表明该方法是本地方法,需要c语言来实现方法体。
public native String helloFromC();
/***这就是创建一个c函数,供native层来调用,所以名字很重要***/
4. 在jni文件夹中定义C语言写的函数实现这个方法,在c文件中添加<jni.h>头文件 ,这样才能识别jstring,env等那些东西
函数格式为
jni对应的返回值类型 Java_包名_方法名(两个必填参数){}
注意:数据类型不要搞错;
Java的j是大写;
包名里面的点最好都换成下划线
JNIEnv* env:是一个java虚拟即的地址指针,是个二级指针,因为env本来就是一个指针,再*一下就是二级指针
jobject obj:调用该c方法的对象,就这样照写
jstring Java_com_itheima_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj)//虽然本地native方法中helloFromc是无参方法,但是C语言中的必须加上这两个参数
5. 返回一个字符串,用c定义一个字符串
char* cstr = "hello from c";
6. 把c的字符串转换成java的字符串
jstring jstr = (*env)->NewStringUTF(env, cstr);
return jstr;
前面都是定义部分,定义好C语言后要编译,编译就需要用到ndk工具来进行编译,就要讲法ndk配置进环境变量 ,
配制方法就是把 路径:\android-ndk-r9b 加进path
7. 在jni中创建Android.mk文件 ,文件里面的内容:
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VERS)
编译生成的类库起个名字
LOCAL_MODULE:=heihei//这里同样可以叫Hello
要编译的C语言文件
LOCAL_SRC_FILES:=Hello.c
include $(BUILD_SHARED_LIBRARY)
8. 在jni文件夹下打开cmd后执行ndk-build.cmd指令
9. java代码中加载so类库,调用本地方法。写在静态代码块中Static{loadLibrary(“库名”);}
-------------------mk文件详解start--------------
# $是调用编译工具链中的函数, 这里的作用是获取当前文件目录.
LOCAL_PATH := $(call my-dir)
# 清空并初始化编译工具链的变量.
# 注意: 会清空所有的LOCAL_变量, 但不会清空LOCAL_PATH的变量.
include $(CLEAR_VARS)
# 编译出来文件的名字, 编译系统会在名字前加lib前缀. 如果已经写lib, 不会再添加.
# 注意: 不可以加扩展名.
LOCAL_MODULE := atguigu
# 指定编译的源文件.如果多个源文件可以用空格连接起来
LOCAL_SRC_FILES := hello.c
# 指定编译文件类型
# 动态库(BUILD_SHARED_LIBRARY) 扩展名:.so 体积小.
# 静态库(BUILD_STATIC_LIBRARY) 扩展名:.a 体积大.
include $(BUILD_SHARED_LIBRARY)
----------------mk文件详解end------------------
AS下使用JNI(as版本1.5完美,其他版本有问题
)
1、在main下创建一个jni文件夹,与java同级
2、3、4、5、6和eclipse一样。
然后在project的gradle.properties中添加配置 android.useDeprecatedNdk=true ,为了兼容老版本
7、在app的build.gradle文件中的defaultConfig{}里面添加
ndk{
moduleName "Hello" //so文件: lib+moduleName+.so ,Hello就是后来要用的so库名
abiFilters "armeabi", "armeabi-v7a", "x86" //cpu的类型
}
然后build项目,使项目生成so文件,生成的so文件在app\build\intermediates\ndk\debug\lib下。
生成的链接库名叫“libHello.so”,当然我们也可以不写这段代码,也能编译生成so库,生成的名字是“libapp.so”,建议还是写上,不然多了就不行了
在这里我们会发现步骤7不同,as的少了创建mk文件这个步骤,其实as已经帮我们创建了,因为我们的在gradle文件中进行了配置
8、回到本地方法native那里,在写native方法之前加载so库,System.loadLibrary("Hello");通常这行代码写在代码块或静态代码块中。这样一样我们的native方法就会到Hello库中去找与之对应的c函数,其实我们更应该在创建native方法的时候就这样写,后面要build之前确定moudleName是否与我们加载的这个库名
欢迎光临 安卓篱笆 (http://www.okapk.cn/)
Powered by Discuz! X3.2