您的位置:首页 > 编程语言 > Java开发

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

2016-07-28 22:37 639 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: