有关JNI的开发技术,我们继续围绕Android平台进行,JNI可以支持C或C++,从目前为止我们写过的JNI代码均为C实现的,即文件名为.C而C++的和这些有什么不同呢? Android平台上的JNI一般使用C还是C++编写呢?
Android平台在中间层和大部分的类库的底层使用了C++的开发方式,后缀为.cpp,比如Android Framework、OpenCore、Webkit、SQLite等等。使用C++好处就是可以使用很多库但目前Android不支持STL,我们知道C表示字符串都是字符数组,但C++可以使用类似string这样的类型表示。
1. 代码上编写C和C++有啥区别
这里Android123就以将Java的unicode字符串转为jni中的utf8,然后再返回一个jstring类型为例子,可以看到jni和java之间字符串的转换方法。
C的实现:
JNIEXPORT jstring JNICALL Java_Android123_CwjC (JNIEnv *env, jobject obj, jstring string)
{
const char *strUTF = (*env)->GetStringUTFChars(env, string, 0);
char szBuffer[255];
strcpy(szBuffer, strUTF);
(*env)->ReleaseStringUTFChars(env, string, strUTF);
return (*env)->NewStringUTF(env, szBuffer);
}
C++的实现:
JNIEXPORT jstring JNICALL Java_Android123_CwjCpp (JNIEnv *env, jobject obj, jstring string)
{
const char *strUTF = env->GetStringUTFChars(string, 0);
char szBuffer[255];
strcpy(szBuffer, strUTF);
env->ReleaseStringUTFChars(string, strUTF);
return env->NewStringUTF(szBuffer);
}
我们加粗了主要区别的关键字,可以看到C++的代码更简练。
2. JNI操作数组代码
JNI中处理数组通用对象为jobjectArray 当然常规的类型比如整形为jintArray,布尔型为jbooleanArray,但没有出现jstringArray这样的类型,有关字符数组的处理我们将在下次的 Android JNI开发进阶篇 详细说明 。处理数组时我们需要考虑数组的长度不能为0才能继续操作,不然就会有访问越界等问题,在JNI中提供了通用类型的GetArrayLength函数。我们从Java传入一个以整形数组,在JNI中将每个元素相加为例返回一个整形告诉Java运算的结果。
JNIEXPORT jint JNICALL Java_Android123_CwjTest (JNIEnv *env, jobject obj, jintArray array)
{
int sum = 0;
jsize length = (*env)->GetArrayLength(env, array); //获取数组长度
if(length==0) //防止异常发生,如果是空的需要返回了
return 0;
jint *pointer = (*env)->GetIntArrayElements(env, array, 0); //获取数组指针
for (int i=0; i<length; i++)
{
sum += pointer[i]; //相加每个数组元素
}
(*env)->ReleaseIntArrayElements(env, array, pointer, 0); //释放内存,这个不能忘了
return sum;
}
如何在JNI中构造一个数组呢? Android开发网给大家一个简单的示例,返回一个整形数组:
JNIEXPORT jobjectArray JNICALL
Java_Android123_CwjTest2(JNIEnv *env, jclass clazz)
{
jobjectArray result; //定义返回对象
jclass intArrayClazz = (*env)->FindClass(env, "[I"); //查找整形数组
if (intArrayClazz == NULL)
{
return NULL;
}
result = (*env)->NewObjectArray(env, size, intArrayClazz, NULL); //构造一个新的数组对象
if (result == NULL)
{
return NULL;
}
for (int i = 0; i < 10 ; i++) //循环10次
{
jint szBuffer[256];
int j;
jintArray newIntArray = (*env)->NewIntArray(env, 10); //构造10个整形数组
if (newIntArray == NULL)
{
return NULL;
}
for (j = 0; j < 10 ; j++) //10个
{
szBuffer[j] = i + j;
}
(*env)->SetIntArrayRegion(env, newIntArray, 0, 10, szBuffer); //设置长度为10个
(*env)->SetObjectArrayElement(env, result, i, newIntArray);
(*env)->DeleteLocalRef(env, newIntArray);
}
return result;
}
3. JNI中有关异常的处理
JNI中抛出异常没有try...catch这样的,而是直接抛出错误
方法1: 使用ThrowNew,比如IOException类发生了FileNotFound
(*env)->ThrowNew(env,(*env)->FindClass("java/io/IOException"),"CWJLog Error, IOException");
方法2: 使用Throw,自己构造
jclass clazz = (*env)->FindClass(env, "java/io/IOException");
jmethodID methodId = (*env)->GetMethodID(env, clazz, "<init>", "()V");
jthrowable throwable = (*env)->NewObject(env, clazz, methodId);
(*env)->Throw(env, throwable);
分享到:
相关推荐
有关JNI的开发技术,我们继续围绕Android平台进行,JNI可以支持C或C++,从目前为止我们写过的JNI代码均为C实现的,即文件名为.C而C++的和这些有什么不同呢?Android平台上的JNI一般使用C还是C++编写呢? 有关JNI的...
Android JNI 开发 步骤 , 绝对详细
一个简单的android JNI 开发范例. 可以做入门学习之用
android JNI开发演示(串口收发) ndk开发,串口收发,生产so库,有代码有开发说明文档,jni开发环境配合
该Demo是我在实际项目中使用到的JNI常用技术总结和提炼,是另一个Android JNI开发培训课件对应的Demo
这是一个jni开发的小例子,具体 的实现步骤在博客:Android关于JNI开发(1)-----eclipse工具开发。里面写的有。需要的朋友可以搜出来看一下。
总结了Android下jni开发的一些重要知识点,并且以代码的形式提供供大家参考
android jni 实现 RSA 3DES AES MD5 BASE64 加密,基于openssl
传智播客android NDK JNI编程
在jni中获取android 设备的mac地址
android jni开发入门,开发工具android studio 2.3.1
android jni开发手册,包含jni调用的各种示例。很好的学习资料
周工总结的jni开发流程
android jni 入门开发指导,想要了解安装jni的可以在此找到。
转载几篇介绍android jni开发方法的文章,有介绍基础的,有介绍方法的,也有实例可参考。
Android JNI Android JNI 用C函数写本地库读写文件,底层调用小例子用C函数写本地库读写文件,底层调用小例子
NDK开发环境安装和一个简单的JNI例子
这是Android NDK开发标准的JNI和Android.mk编写模版,里面的一些东西可能涉及我的项目,但不影响观看
这是Android的NDK开发之Android JNI调用流程程一个demo。下载下来可以直接在android studio上运行。
简单的android串口收发,用jni开发