Android JNI开发提高篇
有关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);
/**
* @author 张兴业
* 邮箱:xy-zhang#163.com
* android开发进阶群:278401545
*
*/
Android JNI开发提高篇的更多相关文章
- Android应用开发提高篇(1)-----获取本地IP
链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/21/2361802.html 一.概述 习惯了Linux下的网络编程,在还没用智能机之前就一直想 ...
- Android应用开发提高篇(6)-----FaceDetector(人脸检测)
链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/10/2388776.html 一.概述 初次看到FaceDetector这个类时,心里想:And ...
- Android应用开发提高篇(4)-----Socket编程(多线程、双向通信)
链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/04/2379628.html 一.概述 关于Socket编程的基本方法在基础篇里已经讲过,今天把 ...
- Android应用开发提高篇(5)-----Camera使用
链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/06/2382679.html 一.概述 Camera是手机的一个很重要的设备,可以说现在的每一部 ...
- Android应用开发提高篇(3)-----传感器(Sensor)编程
链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/29/2373420.html 一.概述 Android支持的传感器种类越来越多了,这确实是一件可 ...
- Android应用开发提高篇(2)-----文本朗读TTS(TextToSpeech)
链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/26/2368696.html 一.概述 TextToSpeech,就是将文本内容转换成语音,在其 ...
- android 串口开发第二篇:利用jni实现android和串口通信
一:串口通信简介 由于串口开发涉及到jni,所以开发环境需要支持ndk开发,如果未配置ndk配置的朋友,或者对jni不熟悉的朋友,请查看上一篇文章,android 串口开发第一篇:搭建ndk开发环境以 ...
- JNI 开发基础篇:Android开发中os文件的探索
正题: android开发中,时长会遇到os文件的使用,那么os文件到底是什么?在这篇文章中会进行说明. .os文件在android中意味着C语言书写的方法,经android提供的ndk进行编译,从而 ...
- Android应用开发基础篇(1)-----Button
Android应用开发基础篇(1)-----Button 一.概述 Button,顾名思义就是按钮的意思,它主要的功能是响应用户按下按钮时的动作. 二.应用 新建一个工程, ...
随机推荐
- 【转】Eclipse自动补全的设置方法
转自:http://blog.csdn.net/xiadasong007/archive/2009/11/11/4799715.aspx 打开 Eclipse -> Window -> P ...
- MFC窗口实现最小化到托盘 右键菜单和还原
//.h文件 void toTray();//最小化到托盘 void DeleteTray();//删除托盘图标 afx_msg LRESULT OnShowTask(WPARAM wParam,LP ...
- JavaScript 的 Promise
先看这个 http://www.html5rocks.com/zh/tutorials/es6/promises/#toc-api [JavaScript Promise 浏览器支持的Promise ...
- Hadoop基准测试(转载)
<hadoop the definitive way>(third version)中的Benchmarking a Hadoop Cluster Test Cases的class在新的版 ...
- 注册表与盘符(转victor888文章 )
转自: http://blog.csdn.net/loulou_ff/article/details/3769479 写点东西,把这阶段的研究内容记录下来,同时也给研究相关内容的同志提供参考, ...
- 自增字段 auto_commit的研究分析
MySQL自增字段,自增字段计数器在主存储里面,不在硬盘上(This counter is stored only in main memory, not on disk). 1,添加表,设立自增主键 ...
- java程序错误类型及异常处理
一.程序的错误类型 在程序设计中,无论规模是大是小,错误总是难免的.程序的设计很少有能够一次完成,没有错误的(不是指HelloWorld这样的程序,而是要实现一定的功能,具备一定实用价值的程序),在编 ...
- 毕业bg(dfs)
毕业bg Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submissi ...
- 关于android 双击事件
大家好,关于android双击事件 我相信大家都知道 API中是有个方法的,但是必须在Activity中在能使用. 对于到底用不用android 双击事件API各有各的看法. 在Activity中使用 ...
- HDU3415:Max Sum of Max-K-sub-sequence(单调队列)
Problem Description Given a circle sequence A[1],A[2],A[3]......A[n]. Circle sequence means the left ...