0
点赞
收藏
分享

微信扫一扫

Android使用JNA体会心得

JNA(Java Native Access)技术也许大家用的很少,其实他也是java官方支持的,并且在github上不断更新着。它主要用在你不需要去编写c++代码,而只是直接使用编译好的独立so库。假设我们编译了独立的so库,此时我们也没有别的需求,仅仅调用so库方法使用功能,就是最好的选择。

Android使用JNA体会心得_github

1. JNA的使用需要依赖2个jar和一个so库

jna-min.jar

jna-platform.jar

libjnidispatch.so

https://github.com/java-native-access/jna/tree/5.14.0/dist,github官方下载

其中 libjnidispatch.so 是下载对应的arm解压出来的so, 比如从下载 android_aarch64.jar 中解压得到,其中aarch64表示 arm64-v8a平台


2. JNA使用介绍

假设我们编译了一个 libmyadd.so,其头文件如下

#ifndef MYADD_H
#define MYADD_H

#include <stdint.h>
// 如果使用JNA这里一定要extern "C", 否则函数名被重载
#ifdef __cplusplus
extern "C" {
    typedef void(*RequestCallback) (uint32_t iVal_ID, uint32_t _resp_data);
    
    int addh(int x, int y);
    int UpdateStatus(uint32_t iArray_ArraySize, uint32_t iArray_RouteIDList[3]);
    int RequestRegister(RequestCallback _cb);
}
#endif

#endif


然后我们使用JNA调用so里的方法,其声明方式如下:

// 注意包导入
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Callback;

interface JNATest extends Library {
    JNATest INSTANCE = (JNATest) Native.load("myadd", JNATest.class);
    public int addh(int x, int r);
    int UpdateStatus(int x, long[] routeidlist);
    int RequestRegister(RequestRegisterCallBack cb);
}

interface RequestRegisterCallBack extends Callback {
    void registerCallBack(int routeID, int _resp_data);
}

JNATest 演示了常用的3种用法,用法主要体现在参数上面,这里是最大的坑。初次使用时特别容易犯错。

我们看addh,UpdateStatus,RequestRegister 其实就对应了c++种头文件的函数。

1)这里面有两个核心的地方,即需要继承 Library 和 Callback。其中Callback用于带有so库中有回调方法时的使用。

2)我们可以看到 UpdateStatus 中的第二个参数用的是 long[],而不是ArrayList<Long>,JNA不支持使用ArrayList。

3)RequestRegister中的参数是接口类型,那么JNA在声明时,一定要 extends Callback。


2. JNA使用示例

通过以上的分析,那就把这3个函数调用试试

int c= JNATest.INSTANCE.addh(11,222);
long[] arr= new long[]{};
int c2= JNATest.INSTANCE.UpdateStatus(11, arr);
int c3= JNATest.INSTANCE.RequestRegister(new RequestRegisterCallBack() {

  @Override
    public void registerCallBack(int routeID, int _resp_data) {

  }
});
Log.e("MainActivity2", "JNA返回1:" + c);
Log.e("MainActivity2", "JNA返回2:" + c2);
Log.e("MainActivity2", "JNA返回3:" + c3);

调用其实也很简单,总的来说,JNA的使用比JNI方便多了,但是它只适合你不需要去编码C++的业务。

举报

相关推荐

0 条评论