Native层与java层之间的数据传递代码实例

这篇博客详细介绍了在Android中如何实现Native层与Java层之间的数据传递,通过具体的MainActivity和NdkLib示例,结合Student类,利用JNI目录下的ndk_lib.cpp文件,展示了在android studio 2.1.2环境下操作的实例代码。提供了完整的代码链接以供参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Native 层与 java 之间的 数据传递


MainActivity

package com.a18459.myapplication;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    String name = "hello";

    NdkLib ndkLib;
    String string;
    TextView tv;
    Student student;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //使用NDK
        ndkLib = new NdkLib();


//------------------------------从java层获取Native层数据--------------------------------------

        //在Native层获得字符串
        string = ndkLib.getNativeString();
        tv = (TextView) findViewById(R.id.tv);
        tv.setText(string);

        //在Native层获得一维数组
        ndkLib.getArray(5);

        //在Native层获得二维数组
        ndkLib.getTwoArray(5);

        //在Native层获得类对象
        student = ndkLib.getStudentFromJNI();
        string = "id: "+ student.getId() + "\n" + "name: " + student.getName();
        tv.setText(string);


//------------------------------从Native层获取java层数据-------------------------------------

        //在Native层操作java层的类中的属性name的值
        Log.i("name: ", ndkLib.name);
        //在Native层修改了成员变量name的值
        ndkLib.Print();
        Log.i("name: ", ndkLib.name);

        //在Native层操作java层的类中的方法,
        ndkLib.doCallBack();
    }
}

NdkLib

package com.a18459.myapplication;

import android.util.Log;

/**
 * Created by 18459 on 2016/7/1.
 */
public class NdkLib {
    //加载ndk库
    static{
        System.loadLibrary("ndk_lib");
    }
    //定义ndk库中的导出函数
    //获得字符串
    public native String getNativeString();
    //获得一维数组
    public native int[] getArray(int nSize);
    //获得二维数组
    public native int[][] getTwoArray(int nSize);
    //获得类对象
    public native Student getStudentFromJNI();

//---------------------------------------------------------------------------------

    //在Native层操作java层的类,改变类中的属性name的值
    public native void Print();
    String name = "hello";

    //在Native层操作java层的类中的方法,
    public native void doCallBack();
    //Native层会调用callback()方法
    public void CallBack(String string){
        Log.i("CallBack2",string);
    }
}

Student

package com.a18459.myapplication;

/**
 * Created by 18459 on 2016/7/2.
 */
public class Student {

    public Student(){}

    public Student(int id,String name){
        this.id = id;
        this.name = name;
    }

    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Jni目录下:

ndk_lib.cpp

#include <jni.h>
#include <android/log.h>
#include <string.h>

extern "C" JNIEXPORT jstring JNICALL
Java_com_a18459_myapplication_NdkLib_getNativeString(JNIEnv *env, jobject instance) {
    return env->NewStringUTF("我是字符串");
}

//返回一维数组
extern "C" JNIEXPORT jintArray JNICALL
Java_com_a18459_myapplication_NdkLib_getArray(JNIEnv *env, jobject instance, jint nSize) {
    //构建jint型一维数组
    jintArray intArray =env->NewIntArray(nSize);
    jint temp[10]  ;  //初始化一个容器,假设 dimion  < 10 ;
    for( int j = 0 ; j < nSize ; j++)
    {
        temp[j] = j  ;
        __android_log_print(ANDROID_LOG_DEBUG,"hellondk","data! %d", temp[j]);
    } //赋值
    //设置jint型一维数组的值
    env->SetIntArrayRegion(intArray, 0 , nSize ,temp);

    // 必须有返回值!!
    return intArray;

}

// 返回二维数组,即返回对象数组,因为没有JNI类型直接表示二维数组
extern "C" JNIEXPORT jobjectArray JNICALL
Java_com_a18459_myapplication_NdkLib_getTwoArray(JNIEnv *env, jobject instance, jint nSize) {

    // 获取一维数组的class类型
    jclass jArrayClass = env->FindClass("[I");//数组的域描述符
    // 创建二维数组
    jobjectArray jobjectArray1;
    jobjectArray1 = env->NewObjectArray(nSize, jArrayClass,0);
    // 初始化数组
    for (int i = 0; i <nSize ; ++i) {
        // 构造二维数组的数组元素,即一维数组
        //构建jint型一维数组
        jintArray intArray = env->NewIntArray(nSize);
        jint temp[10]  ;  //初始化一个容器,假设 dimion  < 10 ;
        for( int j = 0 ; j < nSize ; j++)
        {
            temp[j] = j  ;
            __android_log_print(ANDROID_LOG_DEBUG,"hellondk","data! %d", temp[j]);
        } //赋值
        //设置jint型一维数组的值
        env->SetIntArrayRegion(intArray, 0 , nSize ,temp);
        // 设置对象数组的值
        env->SetObjectArrayElement(jobjectArray1,i,intArray);
        env->DeleteLocalRef(intArray);  //删除局部引用
    }
    //要返回
    return jobjectArray1;
}

//返回类的对象
extern "C" JNIEXPORT jobject JNICALL
Java_com_a18459_myapplication_NdkLib_getStudentFromJNI(JNIEnv *env, jobject instance) {

    // 创建对象
    jobject jstudent;
    // 1.获取类型
    jclass jsutdentclass = env->FindClass("com/a18459/myapplication/Student");
    // 2.通过类型获取构造方法ID
    jmethodID jmethodID1 = env->GetMethodID(jsutdentclass,
            //<init>是指构造函数方法
                                            "<init>",
            //构造函数Student(int id,String name)的描述符,v代表返回值问void
                                            "(ILjava/lang/String;)V");
    jstring jname = env->NewStringUTF("我来自Student类");
    // 3.创建对象
    jstudent = env->NewObject(jsutdentclass,jmethodID1,1,jname);

    return jstudent;
}

//此方法应为成员方法
//在Native层调用java层类中属性,并修改值
extern "C" JNIEXPORT void JNICALL
Java_com_a18459_myapplication_NdkLib_Print(JNIEnv *env, jobject instance) {

    // 1.根据对象获取类型
    jclass jobjectcls = env->GetObjectClass(instance);

    // 2.根据类型获取域ID
    jfieldID jfieldID1 = env->GetFieldID(jobjectcls,"name","Ljava/lang/String;");

    // 3.根据域ID获取成员变量
    jstring jstring1 = (jstring)env->GetObjectField(instance,jfieldID1);
    //int len = env->GetStringUTFLength(jstring1);
    // GetStringUTFChars 返回指针,直接操作NativeTypes字符串
    // GetStringUTFRegion 返回字符串内容,必须缓冲区有值
    char* name = (char*)env->GetStringUTFChars(jstring1,0);
    //Native层的log调试输出
    //__android_log_print(ANDROID_LOG_DEBUG, "ndk_lib","NdkLib! %s", name);

    // 设置成员变量的值
    //构造一个jString对象
    char * c_ptr_name = "在Native层修改了java层成员变量name的值" ;
    jstring cName = env->NewStringUTF(c_ptr_name);
    // 设置该字段的值
    env->SetObjectField(instance , jfieldID1 , cName);
    //释放局部引用
    env->ReleaseStringUTFChars(jstring1, name);
}

//此方法应为成员方法
//在Native层调用java层类中方法,并给方法传参数
extern "C"JNIEXPORT void JNICALL
Java_com_a18459_myapplication_NdkLib_doCallBack(JNIEnv *env, jobject instance) {

    // 1.根据对象获取类型
    jclass jobjectcls = env->GetObjectClass(instance);

    // 2.根据类型获取方法ID
    jmethodID jmethodID1 = env->GetMethodID(jobjectcls,
                                            "CallBack",
                                            "(Ljava/lang/String;)V");
    jstring jname = env->NewStringUTF("在Native层调用java层方法");
    // 3.根据方法ID调用方法,并传递参数
    env->CallVoidMethod(instance,jmethodID1,jname);
}

使用工具: android studio 2.1.2

实例代码:链接:http://pan.baidu.com/s/1eSAxmxW 密码:5bwp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值