建立JNI层的本地对象,并与JAVA层交互方法

  最近在做OpenCV4Android开发的时候,需要从摄像头捕获多个图片,传值给本地对象,每次捕获到图片都更新数据,最后将计算得到的数据传给JAVA层,并在界面中显示。经过摸索和调试后,找到了通过本地对象的地址,来实现JAVA和本地类交互的方法。

  下面,通过一个小例子进行示例说明,本例子完成通过点击按钮控件,实现本地对象的成员数据自加,并显示的功能:

首先这是我们C++类的代码,能实现自加很简单的类,能完成测试就好:

class TestNDK{
private:
    int num;
public:
    TestNDK():num(0){
    }
    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:

时间: 2024-08-29 07:43:14

建立JNI层的本地对象,并与JAVA层交互方法的相关文章

Java层与Jni层的数组传递(转)

源:Java层与Jni层的数组传递 Android开发中,经常会在Java代码与Jni层之间传递数组(byte[]),一个典型的应用是Java层把需要发送给客户端的数据流传递到Jni层,由Jni层的Socket代码发送出去,当然,Jni层也需要把从Socket接收到的数据流返回给Java层.我简单地总结了一下,从Java层到Jni层,从Jni层到JAVA层,各有3种传递方式,下面用代码示例简单地介绍一下. 示例代码的主要文件有两个,一个是Native.java,是Java层的类:另一个是Nati

Android开发实践:Java层与Jni层的数组传递

Android开发中,经常会在Java代码与Jni层之间传递数组(byte[]),一个典型的应用是Java层把需要发送给客户端的数据流传递到Jni层,由Jni层的Socket代码发送出去,当然,Jni层也需要把从Socket接收到的数据流返回给Java层.我简单地总结了一下,从Java层到Jni层,从Jni层到JAVA层,各有3种传递方式,下面用代码示例简单地介绍一下. 示例代码的主要文件有两个,一个是Native.java,是Java层的类:另一个是Native.c,是JNI层的文件,关键的地

转:Android开发实践:Java层与Jni层的数组传递

Android开发中,经常会在Java代码与Jni层之间传递数组(byte[]),一个典型的应用是Java层把需要发送给客户端的数据流传递到Jni层,由Jni层的Socket代码发送出去,当然,Jni层也需要把从Socket接收到的数据流返回给Java层.我简单地总结了一下,从Java层到Jni层,从Jni层到JAVA层,各有3种传递方式,下面用代码示例简单地介绍一下. 示例代码的主要文件有两个,一个是Native.java,是Java层的类:另一个是Native.c,是JNI层的文件,关键的地

(转)java 层调用Jni(Ndk) 持久化c c++ 对象

对于Jni(Ndk) 很多人应该都有印象,Android的ndk接触到的机会相对会比较多,本例子以android平台为例,pc端的话就以简单的windows为例, 编码完用vs 或是 gcc进行编译成dll文件,扔到系统system32 , 就是环境变量配置的文件夹底下,linux 可能也差不多是这个意思,剩下的代码就跟android一样,进行加载这个动态链接库即可. 这里就不做赘述,直接进入android平台的ndk开发,这里就主要讲下,Java层如何持久化c c++ 对象,场景可以是这样,假

Andorid Binder进程间通信---Binder本地对象,实体对象,引用对象,代理对象的引用计数

本文参考<Android系统源代码情景分析>,作者罗升阳. 一.Binder库(libbinder)代码: ~/Android/frameworks/base/libs/binder ----BpBinder.cpp ----Parcel.cpp ----ProcessState.cpp ----Binder.cpp ----IInterface.cpp ----IPCThreadState.cpp ----IServiceManager.cpp ----Static.cpp ~/Androi

操作JNI函数以及复杂对象传递

转自:http://blog.csdn.net/qinjuning/article/details/7607214 在掌握了JNI函数的使用和相关类型的映射后,以及知晓何利用javah工具生成对应的jni函数以及如何生成动态 链接库 (windos下就是.dll库,Linux就是.so库了,不懂在Window下生成dll动态库的,具体流程可看我的这篇博客: <Android中JNI的使用之一:Java原生JNI的使用.javah指令的使用以及图解教材>).即可掌握JNI的使用了了. 总的来说,

WPF——数据绑定(二)绑定方法—绑定本地对象

注意:本人初学WPF,文中表达或技术性问题请勿见怪,欢迎指正,谢谢 标记拓展语法:绑定到本地对象 什么是绑定到本地对象,我个人理解就是实现UI层上两个或多个控件的相互关联,一个控件的状态改变,导致另一个控件状态随机改变, 废话不多说,直接贴上代码,代码目的是实现一个TextBox和CheckBox的相互关联,选中CheckBox,则TextBox可用,否则不可用. <!--MainWindow.xaml--> <Window x:Class="Binding_1.MainWin

从java层到framework到JNI到HAL到kernel的hello 例子

转载自 http://blog.csdn.net/Luoshengyang/article/category/838604/3 在智能手机时代,每个品牌的手机都有自己的个性特点.正是依靠这种与众不同的个性来吸引用户,营造品牌凝聚力和用户忠城度,典型的代表非iphone莫属了.据统计,截止2011年5月,AppStore的应用软件数量达381062个,位居第一,而Android Market的应用软件数量达294738,紧随AppStore后面,并有望在8月份越过AppStore.随着Androi

TP框架---Model模型层---做模型对象

TP框架----Model模型层---------------做模型对象 Model模型层是用来做什么的呢???? 主要是用来做操作数据库访问的. 也就说明TP框架自带了一种访问数据库的方式,使用的是Model模型. Model模型怎样使用呢??? 要使用Model模型层访问数据库的话,需要做配置,因为必须把数据库的一些参数配置好之后,才能连接,所以找到Config.php 配置文件,打开 这些是关于数据库的配置, 要把这些粘贴到config.php 进行修改. config.php配置文件(修