华为css配置实例:【转】Android JNI开发提高篇

来源:百度文库 编辑:中财网 时间:2024/05/11 19:36:59
Android JNI开发提高篇 时间:2010-11-04 11:19 来源:未知 点击:98次AndroidJNI开发提高篇,有关JNI的开发技术,我们继续围绕Android平台进行,JNI可以支持C或C++,从目前为止我们写过的JNI代码均为C实现的,即文件名为.C而C++的和这些有什么不同呢? Android平台上的JNI一般使用C还是C++编写呢

有关JNI的开发技术,我们继续围绕Android平台进行,JNI可以支持C或C++,从目前为止我们写过的JNI代码均为C实现的,即文件名为.C而C++的和这些有什么不同呢? Android平台上的JNI一般使用C还是C++编写呢?

Android平台在中间层和大部分的类库的底层使用了C++的开发方式,后缀为.cpp,比如AndroidFramework、OpenCore、Webkit、SQLite等等。使用C++好处就是可以使用很多库但目前Android不支持STL,我们知道C表示字符串都是字符数组,但C++可以使用类似string这样的类型表示。

1. 代码上编写C和C++有啥区别

这里安博中程就以将Java的unicode字符串转为jni中的utf8,然后再返回一个jstring类型为例子,可以看到jni和java之间字符串的转换方法。

C的实现:

JNIEXPORT jstring JNICALL Java__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__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__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

{

sum += pointer[i]; //相加每个数组元素

}

(*env)->ReleaseIntArrayElements(env, array, pointer, 0);//释放内存,这个不能忘了

return sum;

}

如何在JNI中构造一个数组呢? Android开发网给大家一个简单的示例,返回一个整形数组:

JNIEXPORT jobjectArray JNICALL

Java__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"),"CWJLogError, IOException");

方法2: 使用Throw,自己构造

jclass clazz = (*env)->FindClass(env, "java/io/IOException");

jmethodID methodId = (*env)->GetMethodID(env, clazz, "","()V");

jthrowable throwable = (*env)->NewObject(env, clazz, methodId);

(*env)->Throw(env, throwable);

有关JNI的异常,要说的还有很多,我们将在下次详细说明这些。