【Android 開發學習筆記】JNI C/C++ 開發環境設定

Cliff Su
6 min readAug 21, 2019

最近在實習工讀的案子中,需要開發可以對圖片進行編輯的功能,當然也需要有著濾鏡的功能囉!但對我來說要從 0 開始,寫出一個可以很流暢運作的可能是有點困難,所以只好上 Github 尋找開源專案,再稍微客製化一下放到目前的 App 中使用,也因為這套專案濾鏡的功能是使用 JNI 執行 C++ 來處理 Bitmap 圖檔,所以在這個專案中還需要部署 JNI的開發環境,也就是這篇筆記的由來~

稍微簡單介紹一下 JNI Java Native Interface 的用途是可以在 Java 中,執行 呼叫 C/C++ 語言的程式,可以用來處理像是圖片 、音訊這類型在 Java 中比較難處理的應用,詳細細節可以參考 Wiki

1. 新建 Android 專案

在 Android Studio 3.4.1 的環境下建立一個全新的 Android 專案,只需要照著一般的設定即可,並且能正常執行 Hello World 即可,這次不需要動到 layout 的設定

Android Hello World

2. 更改專案目錄

將原本的 Android 目錄顯示方式,切換至 Project 的顯示模式,並且展開資料夾找到 main 資料夾,等等我們需要在 main 底下新增資料夾

專案名稱\app\src\main
更改專案目錄顯示模式

3. 新增 JNI 資料夾

在這裡我們新增一個名為 jni 的資料夾,主要的用途是用來放置我們所寫的 C/C++ 檔案,請注意檔案與資料夾的大小寫

4. 新增 JNI 檔案

我們在 jni 資料夾底下,新增一個 main.c 的檔案,這個檔案就是我們撰寫 C/C++的檔案,這裡我使用 C 語言當作範例,這個檔案的功能可以 return 回傳一段字串到我們的 Java 裡

這段程式碼有個特別的地方需要注意,請務必將 ga_fliptech_androidjni 更換成你自己的 Package Name

#include <jni.h>#include <string.h>// Please note the ga_fliptech_androidjni must to replace to your application package name.jstring Java_ga_fliptech_androidjni_MainActivity_StringFromJNI(JNIEnv* env, jobject thiz) {return (*env)->NewStringUTF(env, "Hello World, Hello JNI");}

5. 新增 Android.mk 檔案

Android.mk 檔主要是用來設定在 Build NDK 時的相關參數,各個參數的說明可以參考這篇 Android Developer Docs

在這裡我們需要注意的是 LOCAL_MODULE LOCAL_SRC_FILES 這兩個參數

LOCAL_MODULE 用來設定我們 C/C++ 模組的名稱

LOCAL_SRC_FILES 用來設定我們 jni 資料夾中,會使用到 C/C++ 的檔案,例如:需要使用到 foo.c 時,就務必將 foo.c 寫上去

6. 新增 Application.mk 檔案

除了前面設定的 Android.mk 之外,還有 Application.mk 需要處理,主要設定 NDK Build 所產生對應指令集的 .so 檔案,細節可以參考 Application.mk

7. 設定 NDK

如果環境沒有 NDK 的話在這裡選擇對應版本進行下載,並且需要設定好系統的環境變數,可以在 CLI 下執行 ndk 等指令

8. 設定專案 NDK 參數

開啟 local.properties 檔案,並設定 NDK 檔案所放置的路徑

9. NDK 編譯

來到我們前面所建立的 jni 資料夾底下,開啟 PowerShell 或是 cmd 的 CLI 工具,來進行編譯

輸入 ndk-build 即可進行編譯,過程中沒有出現 error 的字樣或是特殊顏色的文字,應該是沒什麼太大的問題

10. 新增 jniLibs 資料夾

新增 jniLibs 資料,我們將剛剛編譯完成在 libs 資料中的所有檔案,複製到jniLibs 這個資料夾內

順序為左到右

11. 在 MainActivity 執行 C/C++ function

在 MainActivity.java 中,定義 public native String StringFromJNI();

使用 System.loadlibrary 來載入我們的 C/C++ 模組

static {
System.loadlibrary("main");
}

最後我們簡單的使用 Log.e 來顯示從 C/C++ 函式中所 return 回傳的字串,這樣就算是完成設定 NDK 的開發環境囉!

在這邊附上這次範例的 Code

參考資料

--

--