有关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开发提高篇的更多相关文章

  1. Android应用开发提高篇(1)-----获取本地IP

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/21/2361802.html 一.概述 习惯了Linux下的网络编程,在还没用智能机之前就一直想 ...

  2. Android应用开发提高篇(6)-----FaceDetector(人脸检测)

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/10/2388776.html 一.概述 初次看到FaceDetector这个类时,心里想:And ...

  3. Android应用开发提高篇(4)-----Socket编程(多线程、双向通信)

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/04/2379628.html 一.概述 关于Socket编程的基本方法在基础篇里已经讲过,今天把 ...

  4. Android应用开发提高篇(5)-----Camera使用

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/03/06/2382679.html 一.概述 Camera是手机的一个很重要的设备,可以说现在的每一部 ...

  5. Android应用开发提高篇(3)-----传感器(Sensor)编程

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/29/2373420.html 一.概述 Android支持的传感器种类越来越多了,这确实是一件可 ...

  6. Android应用开发提高篇(2)-----文本朗读TTS(TextToSpeech)

    链接地址:http://www.cnblogs.com/lknlfy/archive/2012/02/26/2368696.html 一.概述 TextToSpeech,就是将文本内容转换成语音,在其 ...

  7. android 串口开发第二篇:利用jni实现android和串口通信

    一:串口通信简介 由于串口开发涉及到jni,所以开发环境需要支持ndk开发,如果未配置ndk配置的朋友,或者对jni不熟悉的朋友,请查看上一篇文章,android 串口开发第一篇:搭建ndk开发环境以 ...

  8. JNI 开发基础篇:Android开发中os文件的探索

    正题: android开发中,时长会遇到os文件的使用,那么os文件到底是什么?在这篇文章中会进行说明. .os文件在android中意味着C语言书写的方法,经android提供的ndk进行编译,从而 ...

  9. Android应用开发基础篇(1)-----Button

    Android应用开发基础篇(1)-----Button   一.概述        Button,顾名思义就是按钮的意思,它主要的功能是响应用户按下按钮时的动作. 二.应用      新建一个工程, ...

随机推荐

  1. spoj 10606 Balanced Numbers 数位dp

    题目链接 一个数称为平衡数, 满足他各个数位里面的数, 奇数出现偶数次, 偶数出现奇数次, 求一个范围内的平衡数个数. 用三进制压缩, 一个数没有出现用0表示, 出现奇数次用1表示, 出现偶数次用2表 ...

  2. 一道Python练习题

    有关字符串与编码的,转自廖雪峰Python教程. 小明的成绩从去年的72分提升到了今年的85分,请计算小明成绩提升的百分点,并用字符串格式化显示出'xx.x%',只保留小数点后1位: # -*- co ...

  3. ExtJS 自定义组件

    主要参考的是官方文档 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  4. jdk outMemory内存溢出

    参数的含义: -vmargs -Xms256M -Xmx768M -Xss256k -XX:PermSize=256M -XX:MaxPermSize=768M -vmargs 说明后面是vm的参数 ...

  5. IOS开发笔记 IOS如何访问通讯录

    IOS开发笔记  IOS如何访问通讯录 其实我是反对这类的需求,你说你读我的隐私,我肯定不愿意的. 幸好ios6.0 以后给了个权限控制.当打开app的时候你可以选择拒绝. 实现方法: [plain] ...

  6. php在apache中运行模式

    php在apache中运行模式 (2011-12-18 02:38:27) 标签: 杂谈 分类: 服务器及软件 一.php在php在三种工作方式:Apache 模块DLL) 以下分别比较: 1. ph ...

  7. CodeIgniter框架开发的统计程序源代码开放

    文章来源: PHP开发学习门户 自己初学php时,用CodeIgniter框架开发的后台统计程序源代码 程序部分页面如图: 具体配置及下载源代码:http://bbs.phpthinking.com/ ...

  8. git学习基础教程

    分享一个git学习基础教程 http://pan.baidu.com/s/1o6ugkGE 具体在网盘里面的内容..需要的学习可以直接下.

  9. Java学习之异常处理

    在 Java 中,所有的异常都有一个共同的祖先 Throwable(可抛出),Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性.       Throwabl ...

  10. HDU1171-Big Event in HDU

    描述: Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don ...