Android:JNA实践(附Demo)
一、JNA和JNI的对比
2.什么是JNA?与JNI有什么差异?
(2)build.gradle 配置
apply plugin: 'com.android.library'
android {
......
sourceSets{
main{
jniLibs.srcDirs = ['src/main/jniLibs']
}
}
......
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
......
}
其中libnanovoice.so对于应的头文件(.h)内容如下:
#ifndef __JB_NANOSIC__H__
#define __JB_NANOSIC__H__ #ifdef __cplusplus
extern "C" {
#endif typedef void (*AppCallback) (char* data,int datalen); int nano_open(AppCallback cb);
int nano_close(void); #ifdef __cplusplus
}
#endif #endif
根据动态库提供的头文件里函数声明,编写JnaNanovoice.java 内容如下:
package com.lxl.nanosic.voice; import com.sun.jna.Callback;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.Pointer; public interface JnaNanovoice extends Library {
public static final String JNA_LIBRARY_NAME = "nanovoice";
public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(JnaNanovoice.JNA_LIBRARY_NAME);
public static final JnaNanovoice INSTANCE = (JnaNanovoice)Native.loadLibrary(JnaNanovoice.JNA_LIBRARY_NAME, JnaNanovoice.class); //直接加载第三方动态库 //定义接口AppCallback,继承自com.sun.jna.Callback
public interface AppCallback extends Callback {
void dataReceived(Pointer data, int datalen);
} //动态库的函数声明
int nano_open(AppCallback cb);
int nano_close();
}
c层和JNA层变量类型有所差异,需要转换:

推荐一个转换工具 :jnaeratorStudio.jar 使用方法:java -jar jnaeratorStudio.jar

(2)调用c库函数,其中Java回调接口需要进一步实现, NanoVoiceRecord.java 中JNA调用部分代码截取如下:
package com.lxl.nanosic.voice; import android.util.Log;
import com.sun.jna.Pointer;
import java.util.LinkedList; public class NanoVoiceRecord { private final String TAG = "NanoVoiceRecord";/**
* 回调函数
*/
private static JnaNanovoice.AppCallback mDataCallback; ...... /** API 2:开始录音 **/
public void start() {
......
// JNA接口
mDataCallback = new JnaNanovoice.AppCallback() {
// 实现接口中的回调
public void dataReceived (Pointer data, int datalen){
if(null != data){
byte[] buffer = data.getByteArray(0, datalen);
int res = OnDataReceived(buffer, datalen);
Log.w(TAG, "...OnDataReceived = " + res + "m_in_q.size=" + m_in_q.size());
} else {
Log.e(TAG, "...Callback data is null !!!");
}
}
};
// 开始录音并传入回调
JnaNanovoice.INSTANCE.nano_open(mDataCallback);
} /** API 3:停止录音 **/
public void stop()
{
JnaNanovoice.INSTANCE.nano_close(); //调用JNA接口退出录音
isRecording=false;
} ...... /**
* 处理c层回调上来的遥控器语音数据方法
*/
public int OnDataReceived(byte[] buffer, int size) {
byte[] bytes_pkg;
int bufferLength; if(m_in_q==null){
return 0;
} bytes_pkg = buffer.clone(); if (m_in_q.size() > 6) { //最多缓存6个包
m_in_q.removeFirst();
}
m_in_q.add(bytes_pkg); ......
}
至此便实现了Java层通过JNA对c层函数的直接调用:

Android:JNA实践(附Demo)的更多相关文章
- winserver的consul部署实践与.net core客户端使用(附demo源码)
winserver的consul部署实践与.net core客户端使用(附demo源码) 前言 随着微服务兴起,服务的管理显得极其重要.都知道微服务就是”拆“,把臃肿的单块应用,拆分成多个轻量级的 ...
- Android 浮动窗口进阶——画中画,浮动视频(附Demo)
今天继续上一篇Android顶层窗口.浮动窗口的进阶应用.上一篇主要讲解了WindowManager服务和如何使用WindowManager编写一个顶层窗口.今天主要是讲讲如何在顶层窗口里面播放视频, ...
- 开源分享:谷歌大佬联合打造《高级Kotlin强化实战(附Demo)》
Kotlin 以其简洁的特性而闻名,而在我们的实践中,更加简洁就意味着更加高效.事实上,在使用 Kotlin 的专业 Android 开发者中,有多达 67% 的人表示 Kotlin 已经帮助他们提升 ...
- fir.im Weekly - 2016 年 Android 最佳实践列表
2016 年已经过去一半,你在年初制定的成长计划都实现了吗? 学海无涯,技术成长不是一簇而就的事情.本期 fir.im Weekly 推荐 王下邀月熊_Chevalier的 我的编程之路--知识管理与 ...
- 学习笔记TF066:TensorFlow移动端应用,iOS、Android系统实践
TensorFlow对Android.iOS.树莓派都提供移动端支持. 移动端应用原理.移动端.嵌入式设备应用深度学习方式,一模型运行在云端服务器,向服务器发送请求,接收服务器响应:二在本地运行模型, ...
- Atitit.嵌入式web 服务器 java android最佳实践
Atitit.嵌入式web 服务器 java android最佳实践 1. Android4.4.21 2. 自己的webserver1 3. CyberHTTP for Java cybergar ...
- 基于socket的客户端和服务端聊天简单使用 附Demo
功能使用 服务端 分离一个不停接受客户端请求的线程 接受不客户端请求的线程中,再分离就收消息的线程 几大对象分别是 IPEndPoint IP终结点 服务端Socket,绑定终结点Bind,启动监听L ...
- Android最佳性能实践(三)——高性能编码优化
在前两篇文章当中,我们主要学习了Android内存方面的相关知识,包括如何合理地使用内存,以及当发生内存泄露时如何定位出问题的原因.那么关于内存的知识就讨论到这里,今天开始我们将学习一些性能编码优化的 ...
- Android最佳性能实践(二)——分析内存的使用情况
由于Android是为移动设备开发的操作系统,我们在开发应用程序的时候应当始终把内存问题充分考虑在内.虽然Android系统拥有垃圾自动回收机制,但这并不意味着我们就可以完全忽略何时去分配或释放内存. ...
随机推荐
- 利用FastReport直接生成条码
procedure TForm1.Button1Click(Sender: TObject); var x:TfrxbarCodeView; begin x:=TfrxbarCodeView.Crea ...
- gitbook 准备一 [python3 WSGI 初探]
目录 1.wsgi服务样例 2.请求样例 1.wsgi服务样例 # 官网样例 from wsgiref.util import setup_testing_defaults from wsgiref. ...
- Django获取用户form表单
首先创建一个Django 的工程项目 前面我们说过了,那到一个项目首先把模板路径,和静态路径在settings.py设置好以后,在开始写代码,写代码也要按照我们以前说的那个工程目录结构写. 现在我们做 ...
- Canvas对画布及文字控制基础API学习
这次纯API练习,比较简单,但是是为了之后的结合项目打基础的,所以也不能忽视它,下面开始: Canvas的平移.旋转.缩放 这里还是以上次画那个青春痘的DEMO为例[http://www.cnblog ...
- 2.Locust 跑起来试试
代码 from locust import HttpLocust, TaskSet, task class UserBehavior(TaskSet): @task def baidu(self): ...
- codeforces#562 Div2 C---Increasing by modulo【二分】
题目:http://codeforces.com/contest/1169/problem/C 题意: 有n个数,每次可以选择k个,将他们+1并对m取模.问最少进行多少次操作,使得序列是非递减的. 思 ...
- Python JSONⅢ
JSON 函数 encode Python encode() 函数用于将 Python 对象编码成 JSON 字符串. 语法 实例 以下实例将数组编码为 JSON 格式数据: 以上代码执行结果为: d ...
- Java 显示调用隐式调用
当你没有使用父类默认的构造方法时,此时在子类的构造方法中就需要显示的调用父类定义的构造方法.比如:父类:class Animal{ private String name; //如果你定义一个新的构造 ...
- Luogu P2567 [SCOI2010]幸运数字 容斥+脑子
双倍经验:BZOJ 2393 Cirno的完美算数教室 做法:先把$[1,r]$中所有的幸运数字筛出来,然后用这些幸运数字来筛$[l,r]$中的近似幸运号码: 剪枝:当一个幸运数字$a[i]$是另一个 ...
- 洛谷【P2257】 YY的GCD
出处:http://www.cnblogs.com/peng-ym/p/8652288.html ( 直接去出处那看就好了 ) 题目描述 神犇YY虐完数论后给傻×kAc出了一题 给定N, M,求 ...