Android技术10:Java与C语言之间简单数据的传递
由于C语言和Java语言之间很多类型不一致性,因此使用native时,需要数据类型转换。下面演示分别传递整型,字符串,整型数组,Java静态方法传递数据。
1.创建native方法
我们单独创建一个NativeClass类来存放native方法
1 package com.forsta.ndk; 2 3 public class NativeClass { 4 public native int add(int x,int y); 5 public native String showString(String str); 6 public native int[] array(int [] a); 7 public static native int sub(int x,int y); 8 }
2.得到对应的头文件
通过在相应的目录下,使用javah com.forsta.ndk.Native,获得com_forsta_ndk_NativeClass.h
1 /* DO NOT EDIT THIS FILE - it is machine generated */ 2 #include <jni.h> 3 /* Header for class com_forsta_ndk_NativeClass */ 4 5 #ifndef _Included_com_forsta_ndk_NativeClass 6 #define _Included_com_forsta_ndk_NativeClass 7 #ifdef __cplusplus 8 extern "C" { 9 #endif 10 /* 11 * Class: com_forsta_ndk_NativeClass 12 * Method: add 13 * Signature: (II)I 14 */ 15 JNIEXPORT jint JNICALL Java_com_forsta_ndk_NativeClass_add 16 (JNIEnv *, jobject, jint, jint); 17 18 /* 19 * Class: com_forsta_ndk_NativeClass 20 * Method: showString 21 * Signature: (Ljava/lang/String;)Ljava/lang/String; 22 */ 23 JNIEXPORT jstring JNICALL Java_com_forsta_ndk_NativeClass_showString 24 (JNIEnv *, jobject, jstring); 25 26 /* 27 * Class: com_forsta_ndk_NativeClass 28 * Method: array 29 * Signature: ([I)[I 30 */ 31 JNIEXPORT jintArray JNICALL Java_com_forsta_ndk_NativeClass_array 32 (JNIEnv *, jobject, jintArray); 33 34 /* 35 * Class: com_forsta_ndk_NativeClass 36 * Method: sub 37 * Signature: (II)I 38 */ 39 JNIEXPORT jint JNICALL Java_com_forsta_ndk_NativeClass_sub 40 (JNIEnv *, jclass, jint, jint); 41 42 #ifdef __cplusplus 43 } 44 #endif 45 #endif
3.实现头文件中方法
1 #include <stdio.h> 2 #include <jni.h> 3 #include<malloc.h> 4 #include "com_forsta_ndk_NativeClass.h" 5 6 7 /** 8 * 返回值 char* 这个代表char数组的首地址 9 * Jstring2CStr 把java中的jstring的类型转化成一个c语言中的char 字符串 10 */ 11 char* Jstring2CStr(JNIEnv* env, jstring jstr) 12 { 13 char* rtn = NULL; 14 jclass clsstring = (*env)->FindClass(env,"java/lang/String"); //String 15 jstring strencode = (*env)->NewStringUTF(env,"GB2312"); // 得到一个java字符串 "GB2312" 16 jmethodID mid = (*env)->GetMethodID(env,clsstring, "getBytes", "(Ljava/lang/String;)[B"); //[ String.getBytes("gb2312"); 17 jbyteArray barr= (jbyteArray)(*env)->CallObjectMethod(env,jstr,mid,strencode); // String .getByte("GB2312"); 18 jsize alen = (*env)->GetArrayLength(env,barr); // byte数组的长度 19 jbyte* ba = (*env)->GetByteArrayElements(env,barr,JNI_FALSE); 20 if(alen > 0) 21 { 22 rtn = (char*)malloc(alen+1); //"\0" 23 memcpy(rtn,ba,alen); 24 rtn[alen]=0; 25 } 26 (*env)->ReleaseByteArrayElements(env,barr,ba,0); // 27 return rtn; 28 } 29 30 JNIEXPORT jint JNICALL Java_com_forsta_ndk_NativeClass_add 31 (JNIEnv *env, jobject obj, jint x, jint y){ 32 return x+y; 33 } 34 35 JNIEXPORT jstring JNICALL Java_com_forsta_ndk_NativeClass_showString 36 (JNIEnv *env, jobject obj, jstring str){ 37 //c语言中没有String类型 38 char* s=Jstring2CStr(env,str); 39 //c语言中的字符串 都是以‘/0‘ 作为结尾 40 char s1[7]={‘ ‘,‘h‘,‘e‘,‘l‘,‘l‘,‘o‘,‘\0‘}; 41 strcat(s,s1); 42 return (*env)->NewStringUTF(env,s); 43 } 44 45 JNIEXPORT jintArray JNICALL Java_com_forsta_ndk_NativeClass_array 46 (JNIEnv *env, jobject obj, jintArray arr){ 47 //1。获取数组长度 48 //2.修改每个数据 49 int size=(*env)->GetArrayLength(env,arr); 50 int * array=(*env)->GetIntArrayElements(env,arr,0); 51 int i=0; 52 for(;i<size;i++){ 53 array[i]+=10; 54 } 55 return arr; 56 57 } 58 JNIEXPORT jint JNICALL Java_com_forsta_ndk_NativeClass_sub 59 (JNIEnv *env, jclass clazz, jint x, jint y){ 60 return x-y; 61 }
4.MainActivity中添加点击事件
1 @Override 2 public void onClick(View v) { 3 int id =v.getId(); 4 switch (id) { 5 case R.id.bt1: 6 int result=nativeClass.add(10, 90); 7 Toast.makeText(getApplicationContext(), "显示结果:"+result, Toast.LENGTH_SHORT).show(); 8 break; 9 case R.id.bt2: 10 Toast.makeText(getApplicationContext(), nativeClass.showString("Forsta"), Toast.LENGTH_SHORT).show(); 11 break; 12 case R.id.bt3: 13 int [] arr={1,2,3,4,5}; 14 nativeClass.array(arr); 15 String s = ""; 16 for(int i:arr){ 17 s+=i+" "; 18 } 19 Toast.makeText(getApplicationContext(),s,Toast.LENGTH_SHORT).show(); 20 break; 21 case R.id.bt4: 22 int result1=NativeClass.sub(90, 10); 23 Toast.makeText(getApplicationContext(), "相减显示结果:"+result1, Toast.LENGTH_SHORT).show(); 24 break; 25 default: 26 break; 27 } 28 29 }
5.演示
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。