硬件平台:迅为iTOP-412开发板

 

安卓开发demoapk 安卓开发板_安卓开发demoapk

 


接下来我们来仿写一个这个方法,我们已打开 led 灯代码为例。

1. 我们先在 MainActivity 里面实现三个方法,分别对应打开,关闭,和控制,我们添加以下代码:

public native int LedOpen();
public native int LedClos();
public native int LedIoctl(int num,int en);

如下图所示:

 

安卓开发demoapk 安卓开发板_android_02

 

2. 然后我们打开 native-lib.cpp 文件,仿写 jin 代码,分别仿写打开,关闭,控制的实现,代码如下:

extern "C" JNIEXPORT jint JNICALL
Java_com_example_jnitest_MainActivity_LedOpen(
JNIEnv* env,
jobject /* this */) {
return 0;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_example_jnitest_MainActivity_LedClos(
JNIEnv* env,
jobject /* this */) {
return 0;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_example_jnitest_MainActivity_LedIoctl(
JNIEnv* env,
jobject /* this */,
jint num,
jint en) {
return 0;
}

如下图所示:

 

安卓开发demoapk 安卓开发板_android_03


3. 接下来我们添加控制 led 的 c 代码,这部分的代码和我们直接用 C 控制 led 的代码是一样的,我们

先添加需要的头文件,代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdint.h>
#include <termios.h>
#include <android/log.h>
#include <sys/ioctl.h>

如下图所示:

 

安卓开发demoapk 安卓开发板_android_04

 

4. 我们在 Java_com_example_jnitest_MainActivity_LedOpen 里面添加打开 led 设备节点的 C 代码:

先添加头文件和 fd 句柄的定义 代码如下

#include <android/log.h>为安卓打印调试信息的头文件。
#include <android/log.h>
int fd = 0;

如下图所示:

 

安卓开发demoapk 安卓开发板_android_05

 

然后在 Java_com_example_jnitest_MainActivity_LedOpen 里面添加打开 led 节点的代码,代码如下:

fd = open("/dev/leds_ctl", O_RDWR | O_NDELAY | O_NOCTTY);
if(fd <= 0){
__android_log_print(ANDROID_LOG_INFO, "serial", "open /dev/leds_ctl Error");
}else{
__android_log_print(ANDROID_LOG_INFO, "serial", "open /dev/leds_ctl Sucess fd=%d", fd);
}

如下图所示:

 

 

安卓开发demoapk 安卓开发板_#include_06

 

5. 在 Java_com_example_jnitest_MainActivity_LedClos 里面添加关闭 fd 的代码,代码如下:

if(fd > 0) close(fd);

如下图所示:

 

安卓开发demoapk 安卓开发板_#include_07

 

6. 在 Java_com_example_jnitest_MainActivity_LedIoctl 添加 led 控制的代码,代码如下:

ioctl(fd,num,en);

如下图所示:

安卓开发demoapk 安卓开发板_Java_08

 

 

7. 我们点击一下编译,这样就可以在默认路径下生成我们这个

 

 

安卓开发demoapk 安卓开发板_android_09

 

我们切换到 project 下面,在默认路径下可以看到我们生成的

 

安卓开发demoapk 安卓开发板_#include_10

 

 

8. 我们可以看到,我们生成的库有 arm64-v8a,armeabi-v7a,x86,x86_64 的库,但是我们实际上并

不需要这么多库,在现阶段,我们需要需要 armeabi-v7a 就可以满足大部分的需求了,armeabi-v7a 兼容

X86,ARMV7,ARMV8,而且这个库生成的路径很不好找,我们能不能改一下他生成的路径并只生成我们需要

的库呢?答案当然是可以的。

(1)更改 so 库的生成目录,我们打开 CMakeList.txt,添加下面的一句设置:

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY

${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})

简化这个设置就是:

set(原路径,目标路径,生成那些平台对应的库文件)

参数解析如下:

CMAKE_CURRENT_SOURCE_DIR:这个是 cmake 的库的原路径

/../jniLibs/:这个是指与 CMakeList.txt 所在目录的同一级目录

ANDROID_ABI :生成那些平台对应的库文件。

我们打开 CMakeList.txt,在里面添加这句代码,代码如下:

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY

${CMAKE_CURRENT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})

如下图所示:

 

安卓开发demoapk 安卓开发板_Java_11

 

 

 

(2)生成指定平台的 so 库,我们打开 gradle,这句代码的意思就是说添加只生成 armeabi-v7a 的库

abiFilters "armeabi-v7a"

如下图所示:

安卓开发demoapk 安卓开发板_Java_12

 

 

 

(3)我们把之前生成的 so 的库删掉,不然编译会出问题,因为不能同时有俩个一样的库,如下图所示:

安卓开发demoapk 安卓开发板_android_13

 

(4)点击编译,编译完成我们就可以在 main 目录下看到我们生成的 armeabi-v7a 的库了,如下图所示:

安卓开发demoapk 安卓开发板_安卓开发demoapk_14

 

这个我们就得到了 so 库,这样既保护了我们的代码,又方便别人使用,那么我们要怎么使用呢?