建立JNI层的本地对象,并与JAVA层交互方法
2024-08-23 19:59:23
最近在做OpenCV4Android开发的时候,需要从摄像头捕获多个图片,传值给本地对象,每次捕获到图片都更新数据,最后将计算得到的数据传给JAVA层,并在界面中显示。经过摸索和调试后,找到了通过本地对象的地址,来实现JAVA和本地类交互的方法。
下面,通过一个小例子进行示例说明,本例子完成通过点击按钮控件,实现本地对象的成员数据自加,并显示的功能:
首先这是我们C++类的代码,能实现自加很简单的类,能完成测试就好:
class TestNDK{
private:
int num;
public:
TestNDK():num(){
}
void numAddSelf(){
num++;
}
int getNum(){
return num;
}
};
然后再写一个JAVA类,通过这个类,加载动态链接库和本地函数,还有与本地方法交互的方法,更利于管理:
package com.pplxlee.testndk; public class TestNDKClass {
// 加载动态链接库
static {
System.loadLibrary("TestNDK");
} // 本地对象的地址,以long的形式保存
private long mAddr; // 构造函数调用本地类的创建函数
TestNDKClass(){
mAddr = nativeCreateObj();
} public void release(){
nativeRelease(mAddr);
} public int getNum(){
return nativeGetNum(mAddr);
} public void numAddSelf(){
nativeNumAddSelf(mAddr);
} private static native long nativeCreateObj(); private static native void nativeRelease(long objAddr); private static native int nativeGetNum(long objAddr); private static native void nativeNumAddSelf(long objAddr); }
下面是实现jni本地方法的代码:
#include <jni.h> extern "C"{ // 构造本地对象,一定要用new关键字构造,否则,方法结束后,对象会被垃圾回收,之后通过地址访问,只会得到随机的“垃圾”
JNIEXPORT jlong JNICALL Java_com_pplxlee_testndk_TestNDKClass_nativeCreateObj(
JNIEnv *, jclass){
TestNDK* ndkObjectAddr = new TestNDK();
return ((long)ndkObjectAddr);
} // 有new就必须有delete,最后不要忘记在本地对象不再需要时,释放其内存
JNIEXPORT void JNICALL Java_com_pplxlee_testndk_TestNDKClass_nativeRelease(
JNIEnv *, jclass, long addrNdkObject){
TestNDK* ndkObjectAddr = (TestNDK*)addrNdkObject;
delete ndkObjectAddr;
} JNIEXPORT jint JNICALL Java_com_pplxlee_testndk_TestNDKClass_nativeGetNum(
JNIEnv *, jclass, long addrNdkObject){
TestNDK* ndkObjectAddr = (TestNDK*)addrNdkObject;
return (ndkObjectAddr->getNum());
} JNIEXPORT void JNICALL Java_com_pplxlee_testndk_TestNDKClass_nativeNumAddSelf(
JNIEnv *, jclass, long addrNdkObject){
TestNDK& ndkObject = *(TestNDK*)addrNdkObject;
ndkObject.numAddSelf();
} }
下面就是我们的MainActivity
public class MainActivity extends Activity { TestNDKClass mObj; TextView tv; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mObj = new TestNDKClass(); tv = (TextView)findViewById(R.id.textView1);
tv.setText(String.valueOf(mObj.getNum())); Button btn = (Button)findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
mObj.numAddSelf();
tv.setText(String.valueOf(mObj.getNum()));
}
}); } @Override
protected void onDestroy(){
super.onDestroy();
mObj.release();
} }
运行结果如下图所示,每次点击按钮,数字都会+1:
最新文章
- 【转】crontab定时任务中文乱码问题
- java.util.logging.Logger使用详解
- xampp下安装yii框架下遇到的问题
- java大数总结【转】
- Java并发——Fork/Join框架
- 树形dp hdu1561
- java集合经常出现空指针问题的解决方案
- windows下搭建node.js及npm的工作环境
- quick-cocos2d-x添加到Pomelo的支持
- Android 开发之错误整理 [2014-04-28 09:22:28 - XXXX] Unable to resolve target &#39;android-18&#39;
- Angular简易分页设计(一):基本功能实现
- 嵌入式linux系统的构建
- [LeetCode] Perfect Number 完美数字
- 24 AIDL案例
- Security - 轻量级Java身份认证、访问控制安全框架
- Spring Day 2
- “adb不是内部或外部命令,也不是可运行的程序或批量文件“
- live555 交叉编译移植到海思开发板
- Centos7部署elasticsearch并且安装ik分词以及插件kibana
- 【可视化】DataV接入ECharts图表库 可视化利器强强联手