Android Studio配置NDK并编译JNI文件so库 APP调用jni源码实例
一、Android studio 版本3.4.1
二、Android studio自带NDK
二、配置javah及ndk-build快速构建工具
1、配置ndk-build 用来编译jni,File-Settings-Tools-External Tools +
Program:C:\Android\Sdk\ndk-bundle\ndk-build.cmd (根据自己NDK的路径填写)
Working directory:$ModuleFileDir$\src\main
2、配置javah 用来自动生成jni头文件,File-Settings-Tools-External Tools +
Program:$JDKPath$\bin\javah.exe
Parameters:-classpath . -jni -d $ModuleFileDir$/src/main/jni $FileClass$
Working directory:$ModuleFileDir$\src\main\java
有的版本Working directory:改为$SourcepathEntry$
$SourcepathEntry$
有时候得修改javah的路径才能编译得过
3、配置好后看到对应新增的menu
三、用javah工具生成jni头文件,并且生成so库。
1、新建nextouch.java文件
package com.example.nextouch;
public class nextouch {
public native int Read_register(int i2c_address,int register_address);
public native int Write_register(int i2c_address,int register_address,int data);
public native int Reset_chip(int period);
}
2、鼠标右键选择javah编译会生成com_example_nextouch_nextouch.h
3、复制生成的.h 文件拷贝到同文件夹下,并把文件后缀改成.c,文件名字可以保持和 .h 文件同名,也可以如上图所示自定义文件名,.c文件内写入的就是各个JNI函数的具体C语言实现。我这里贴出我自己实际用到的com_example_nextouch_nextouch.c
/* DO NOT EDIT THIS FILE - it is machine generated */
#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>
#include "com_example_nextouch_nextouch.h"
#include <jni.h>
#include <android/log.h>
/* Header for class com_example_nextouch_nextouch */
#define TAG "NEXTOUCH"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL, TAG, __VA_ARGS__)
#define CHIPS_DEV_NAME "/dev/nextouch_control"
#define CHIPS_IOC_MAGIC 'k'
#define CHIPS_IOC_SET_RESET_GPIO _IOW(CHIPS_IOC_MAGIC,8,unsigned char)
int fd=-1;
#ifdef __cplusplus
extern "C" {
#endif
static int init_nextouch_i2c_device()
{
int ret;
if((fd = open(CHIPS_DEV_NAME,O_RDWR|O_NDELAY))<0)
{
LOGI("open %s failed",CHIPS_DEV_NAME);
ret=-1;
}
else
{
LOGI("open %s success!\n",CHIPS_DEV_NAME);
ret=0;
}
return ret;
}
/**
* chips_set_reset_gpio - 设置复位gpio电平?? @level: :非0为拉高,0为拉??
* @return: 成功返回0,失败返回负??
*/
static int chips_set_reset_gpio(int level)
{
if(fd < 0)
{
fd = open(CHIPS_DEV_NAME,O_RDWR);
if(fd == -1)
{
LOGE("<%s> Failed to open device for %s",__FUNCTION__,strerror(errno));
return -1;
}
}
if(ioctl(fd,CHIPS_IOC_SET_RESET_GPIO,(unsigned long)&level) < 0)
{
LOGE("<%s> Failed to set reset_gpio state",__FUNCTION__);
return -1;
}
return 0;
}
/*
* Class: com_example_nextouch_nextouch
* Method: Open
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_example_nextouch_nextouch_Read_1register
(JNIEnv *env, jobject obj,jint i2c_addr,jint address)
{
int ret;
unsigned char buffer[3];
buffer[0] = (unsigned char)i2c_addr;
buffer[1] = (unsigned char)address;
buffer[2] = (unsigned char)0;
if(fd <0)
init_nextouch_i2c_device();
ret=read(fd,buffer,1);
if(ret<0)
{
LOGI("i2c read failed! ret=%d errno=%d\n",ret,errno);
return ret;
}
LOGI("Read_register i2c_addr=0x%02x address=0x%02x,data=0x%02x ret=%d",i2c_addr,address,buffer[0],ret);
return buffer[0];
}
/*
* Class: com_example_nextouch_nextouch
* Method: Close
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_example_nextouch_nextouch_Write_1register
(JNIEnv *env, jobject obj,jint i2c_addr,jint address, jint data)
{
int ret;
unsigned char buffer[4];
buffer[0] = i2c_addr;
buffer[1] = 0x02;
buffer[2] = (unsigned char)address;
buffer[3] = (unsigned char)data;
if(fd <0)
init_nextouch_i2c_device();
ret = write(fd,buffer,4);
if(ret<0)
{
LOGI("i2c write failed! ret=%d errno=%d\n",ret,errno);
return ret;
}
LOGI("Write_register i2c_addr=0x%02x,address=0x%02x,data=0x%02x buffer[0]=0x%02x ret=%d",i2c_addr,address,data,buffer[0],ret);
return buffer[0];
}
/*
* Class: com_example_nextouch_nextouch
* Method: Ioctl
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_example_nextouch_nextouch_Reset_1chip
(JNIEnv *env, jobject obj, jint period)
{
int ret;
unsigned char buffer[4];
buffer[0] = 0;
buffer[1] = 0x03;
buffer[2] = (unsigned char)0;
buffer[3] = (unsigned char)period;
if(fd <0)
init_nextouch_i2c_device();
ret = write(fd,buffer,4);
if(ret<0)
{
LOGI("Reset failed!\n");
return ret;
}
//chips_set_reset_gpio(0);
LOGI("Reset_chip address=0x%02x,data=0x%02x buffer[0]=0x%02x",0,period,buffer[0]);
return buffer[0];
}
#ifdef __cplusplus
}
#endif
4、添加Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := nextouch
LOCAL_SRC_FILES := com_example_nextouch_nextouch.c
LOCAL_LDLIBS += -llog
LOCAL_LDLIBS +=-lm
include $(BUILD_SHARED_LIBRARY)
5、添加Application.mk
APP_ABI := armeabi-v7a arm64-v8a
6、ndk-build编译,会在libs下生成两个文件夹
7、到这里已经编译出so库,接下来是如果在app里面调用这些jni接口了。
四、app调用jni接口
1、再需要调用jni接口的java文件里面添加
static {
System.loadLibrary("nextouch");
}
2、调用接口
3、app/build.gradle文件里面添加
sourceSets {
main {
jni.srcDirs = []
//jniLibs.srcDirs = ['libs']// include .so file into apk
jniLibs.srcDirs = ['src/main/libs']// include .so file into apk
// reference: http://stackoverflow.com/questions/24357687/how-to-include-so-library-in-android-studio-really
}
}
4、可以编译了生apk了
5、真机测试ok
五,源码路径:nextouch_jni_demo.zip_Androidstudio编译jni-Linux文档类资源-CSDN下载