標籤:
背景: 最近一個月一直在做移植庫的工作,將c代碼到share library移植到Android平台。這就涉及到Android NDK(native develop kit)內容。這裡只想記錄下JNI(java native interface)經常遇到到問題。
問題1. 忘記delete local reference。帶New到方法(如:NewByteArray)這樣到方法比較好辨認,需要手動調用DeleteLocalRef()來釋放(傳回值除外)。比較特殊的一個方法是:GetByteArrayELement必須要調用ReleaseByteArrayElements進行釋放。當然如果你只是取bytearray中到byte,那麼完全可以用GetByteArrayRegion實現。
問題2. 沒有NewGlobalRef。 在不同線程調用java方法,需要儲存jobject對象,這時需要對jobject對象做全域引用,否則會失效。
問題3. jbytearray的length。在JNI layer擷取到jbytearray到長度是不對到,應該由java擷取byte[]的length再傳給C layer。否則C layer有可能獲得到是亂碼。
問題4. 線程問題。 不同線程使用JNIEnv*對象,需要AttachCurrentThread將env掛到當前線程,否則無法使用env。
問題5. javap 命令是對java的class檔案操作;而javah命令需要在包名到上一層路徑運行才行,否則無法產生.h檔案。
問題6. 盡量避免頻繁調用JNI或者是使用JNI傳輸大量到資料。
問題7. Reference Table overflow (max=1024) 或者是 Reference Table overflow (max=512)一定是因為忘記釋放global reference或者local reference,請仔細檢查代碼。
問題8. 不要在windows下使用cygwin編譯NDK code,那樣會遇到arguments too long問題,因為windows路徑長度有限制導致。雖然可以使用subst將路徑映射為短路徑,但是在編譯時間和調試上,windows到孩子都是傷不起。同樣到build,在windows下要15分鐘左右,而在mac下只要5分多,相差3倍。調試JNI 代碼到速度更是不用提了,差太多。
總結,JNI代碼量其實不是很多,JNI作為一個資料轉送層,它到作用僅僅是java和c直接到橋樑,但是如果處理不好將會是災難,調試和找bug非常困難。
原文連結:http://blog.csdn.net/goof/article/details/12206783
Android NDK之JNI陷阱