Android NDK开发 传统的配置方式(三)

新建一个工程
在main下创建一个jni文件夹

Application.mk文件内容(写你要编译成那些版本的so文件)
APP_ABI := armeabi-v7a x86
Android.mk文件内容
 1 //向编译系统描述 我要编译的文件在什么位置 要生成的文件叫什么名字, 是什么类型
 2 LOCAL_PATH := $(call my-dir)
 3 //清除上次编译的信息
 4 include $(CLEAR_VARS)
 5 LOCAL_CFLAGS+=-pie -fPIE
 6 LOCAL_LDFLAGS+=-pie -fPIE
 7 //在这里指定最后生成的文件的名字
 8 LOCAL_MODULE    := hello
 9 //要编译的C的代码的文件名
10 LOCAL_SRC_FILES := hello.c
11 //编译后的指令集 ARM指令
12 LOCAL_ARM_MODE := arm
13 //依赖库
14 LOCAL_LDLIBS += -llog
15 //要生成的是一个动态链接库
16 include $(BUILD_SHARED_LIBRARY)
java层 代码

生成.h头文件(一定要在src/main/java目录下)
javah -jni -encoding UTF-8  com.qiaorui.jnidemo01.JNI

这下面是生成的.h文件的内容,把这些内容复制到.c文件

c代码
 1 #include <jni.h>
 2 #include<stdlib.h>
 3 #include <android/log.h>
 4 #define LOG_TAG "System.out"
 5 #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
 6 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
 7 
 8 JNIEXPORT jint JNICALL Java_com_qiaorui_jnidemo01_JNI_add
 9   (JNIEnv* env, jobject thiz, jint x, jint y){
10     return x+y;
11   }
12 
13 
14 JNIEXPORT jstring JNICALL Java_com_qiaorui_jnidemo01_JNI_sayHelloInC
15   (JNIEnv* env, jobject thiz, jstring jstr){
16     //把java的字符串转换成c的字符串
17     char* cstr = (*env)->GetStringUTFChars(env,jstr,NULL);
18     //获取c字符串长度
19     int length = strlen(cstr);
20     int i;
21     //for循环执行完 cstr每一个元素都+1了
22     for(i=0;i<length;i++){
23         *(cstr+i)+=1;
24     }
25     return (*env)->NewStringUTF(env,cstr);
26 
27   }
28 
29 
30 
31 JNIEXPORT jintArray JNICALL Java_com_qiaorui_jnidemo01_JNI_arrElementsIncrease
32   (JNIEnv* env, jobject thiz, jintArray jarr){
33       //获取数组的长度
34       int length = (*env)->GetArrayLength(env,jarr);
35        //打印长度
36       LOGD("length=%d",length);
37       //获取数组首地址
38       //jint*       (*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);
39       //jboolean java的boolean类型在C中的表示
40       //这个参数 在有些虚拟机中 用来作为 执行完GetIntArrayElements之后 是否创建了数组的副本的标志
41       //如果创建了副本 就会返回 true 1
42       //如果没创建副本返回false 0 Android中 这个参数不必使用 直接传NULL 没有意义的地址
43       jboolean isCopy = NULL;
44       int* p = (*env)->GetIntArrayElements(env,jarr,NULL);
45 
46       int i ;
47       for(i = 0;i<length;i++){
48           *(p+i)+=10;
49       }
50       //由于获取到了数组的首地址 所以通过指针操作了每一个元素之后 jarr里的每一个元素已经被修改了
51       //所以没有必要创建新的数组 直接把jarr作为返回值返回去
52       return jarr;
53   }

   

在jni目录下输入ndk-build编译

生成的so库

在App文件夹下的build.gradle文件里,找到defaultConfig项,在其项里添加如下代码(必须,否则会导致LoadLibrary时加载失败):

 

运行测试 

 

猜你喜欢

转载自www.cnblogs.com/qiaorui/p/12712176.html
今日推荐