在 Android 上運行 C 語言

Android的應用程式主要是透過Java來開發而Java本身提供了JNI(Java Native Interface)這個機制讓使用Java寫出來的應用程式可以跟其他語言的函式庫做溝通。本篇文章就來介紹如何透過JNI讓Android運行C語言。

參考資料:
在Android使用JNI
Add C and C++ Code to your project
Android Native Development Kit Cookbook - Feipeng Liu

泰勞本身的作業環境如下:
OS: Ubuntu 16.04
IDE: Android Studio 2.1.2
Java: Open JDK 1.8.0_111
NDK: android-ndk-r12b

前置作業:
到官網下載Android NDK將路徑設定好。

#設定NDK路徑
開啟新專案 > 打開local.properties加入NDK路 > ndk.dir=/xxx/yyy/zzz/android-ndk-r12b

#創建JNI目錄 
在main目錄底下創建JNI Folder

#新增Android.mk檔 
在JNI目錄下創建一個Android.mk檔,內容如下:
LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS) 
LOCAL_MODULE    := jni_hello (java要呼叫的名稱)
LOCAL_SRC_FILES := main.c (對應的檔案) 
include $(BUILD_SHARED_LIBRARY)

#新增Application.mk檔 
在JNI目錄下創建一個Application.mk檔,內容如下:

APP_ABI:= all (可在哪些CPU上運行)

#修改build.gradle(Module:app) 
打開build.gradle, 在defaultConfig裡面加入以下內容:

defaultConfig {
    applicationId "chen.kuanlin.jnihello"
    minSdkVersion 21
    targetSdkVersion 25
    versionCode 1
    versionName "1.0"
    ndk {
         moduleName "jni_hello"
    }
}

#新增main.c 在JNI目錄下創建main.c,依照JNI的語法寫入簡單的方法。

#指定Library並宣告Native方法 
在Java裡指定Library並宣告Native方法。

接著只需在主程式裡呼叫StringFromJNI這個Native方法即可得到C語言回傳的字串"Hello JNI!"

打鐵要趁熱再多做一些簡單的練習吧!

#加入運算方法
在JNI目錄下創建math.c,一樣依照JNI的語法寫入簡單的方法。

別忘了在Android.mk裡的LOCAL_SRC_FILES後面加上math.c

並於主程式宣告新增的Native方法。

此時於程式裡呼叫並將參數帶入NativeAddition這個Native方法,就會得到透過C語言運算的結果。

#錯誤訊息 
如果很不幸的在編譯時出現以下錯誤訊息:
Set "android.useDeprecatedNdk=true" in gradle.properties to continue using the current NDK integration.

請在gradle.properties檔案裡加入

android.useDeprecatedNdk=true

#Debug 
有時後會需要加入Log至C語言的部份來做Debug需要遵循以下步驟。

參考資料:
Android-JNI中的log打印

1.加入以下標頭檔

#include <android/log.h>

2.定義LOG標籤與類型

/*定義Log標籤*/
#define TAG "aes-jni-math"
/*定義LOGD類型*/
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__)


3.修改Android.mk 
加入以下內容

LOCAL_LDLIBS := -llog

4.修改build.gradle(app)

ndk {
    moduleName "jni_hello"
    ldLibs "log"
}

5.使用方式

以上就是簡單的實作方式與步驟大家快去動手做作看吧!

留言

這個網誌中的熱門文章

程式語言常用之符號與詞彙 - 中英文對照

什麼是 Bootloader?

Repo 實用指令