編輯:高級開發
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的異常,要說的還有很多,android123將在下次詳細說明這些。
移動開發已經毫無爭議地成為軟件領域的發展趨勢,嶄新的領域和模式不僅僅為各個廠商,也會普通的開發者打開了一扇阿裡巴巴之門。本文摘取自台灣知名技術專家,台灣公認的“OO教父
每一個Android設備特別是手機都提供一個撥打電話功能,但仍然需要編寫一個應用程序,給用戶一個選擇使用硬編碼的電話號碼撥打電話。本章列出了一個簡單的步驟來創建一個應用程
一、安裝 JDK 下載JDK最新版本,下載地址如下: http://www.Oracle.com/technetwork/java/Javase/downloads
可以安裝在用戶設備上的不同版本的SDK。對於android1.5或以上版本,有兩個可用的平台: android Open Source Project 和 Google