Android NDK 面試題彙總
一、談談你對 JNI 和 NDK 的理解
JNI:
JNI 是 Java Native Interface
的縮寫,即 Java 的本地介面。
目的是使得 Java 與本地其他語言(如 C/C++)進行互動。
JNI 是屬於 Java 的,與 Android 無直接關係。
NDK:
NDK 是 Native Development Kit
的縮寫,是 Android 的工具開發包。
作用是更方便和快速開發 C/C++ 的動態庫,並自動將動態庫與應用一起打包到 apk。
NDK 是屬於 Android 的,與 Java 無直接關係。
總結:
JNI 是實現的目的,NDK 是 Android 中實現 JNI 的手段。
二、談談你對 JNIEnv 和 JavaVM 理解
JavaVM
JavaVM 是虛擬機器在 JNI 層的代表。
一個程序只有一個 JavaVM。(重要!)
所有的執行緒共用一個 JavaVM。(重要!)
JNIEnv
JNIEnv 表示 Java 呼叫 native 語言的環境,封裝了幾乎全部 JNI 方法的指標。
JNIEnv 只在建立它的執行緒生效,不能跨執行緒傳遞,不同執行緒的 JNIEnv 彼此獨立。(重要!)
注意:
在 native 環境下建立的執行緒,要想和 java 通訊,即需要獲取一個 JNIEnv 物件。我們通過 AttachCurrentThread
DetachCurrentThread
方法將 native 的執行緒與 JavaVM 關聯和解除關聯。
三、解釋一下 JNI 中全域性引用和區域性引用的區別和使用
全域性引用
通過 NewGlobalRef
和 DeleteGlobalRef
方法建立和釋放一個全域性引用。
全域性引用能在多個執行緒中被使用,且不會被 GC 回收,只能手動釋放。
區域性引用
通過 NewLocalRef
和 DeleteLocalRef
方法建立和釋放一個區域性引用。
區域性引用只在建立它的 native 方法中有效,包括其呼叫的其它函式中有效。因此我們不能寄望於將一個區域性引用直接儲存在全域性變數中下次使用(請使用全域性引用實現該需求)。
我們可以不用刪除區域性引用,它們會在 native 方法返回時全部自動釋放,但是建議對於不再使用的區域性引用手動釋放,避免記憶體過度使用。
擴充套件:弱全域性引用
通過 NewWeakGlobalRef
和 DeleteWeakGlobalRef
建立和釋放一個弱全域性引用。
弱全域性引用類似於全域性引用,唯一的區別是它不會阻止被 GC 回收。
四、JNI 執行緒間資料怎麼互相訪問
考察點和上體類似,執行緒本來就是共享記憶體區域的,因此我們需要使用 全域性引用
。
五、怎麼定位 NDK 中的問題和錯誤
一般在開發階段的話,我們可以通過 log 來定位和分析問題。
如果是上線狀態(即關閉了基本的 log),我們可以藉助 NDK 提供的 addr2line
工具和 objdump
工具來定位錯誤。詳情:so 動態庫崩潰問題定位(addr2line與objdump)
其它還可以使用 C/C++ 的一些分析工具。
廣告
專欄傳送門:Android NDK 從入門到精通(彙總篇)