- 使用Android Studio/New Project 選擇Empty Activity
Name: CreateJNI
2. File/New/Module, 選擇Android Native Library
Module name輸入: nativejnilib
按Finish結束
這時的目錄結構如下,除了 app 以外,多了nativejnilib這個 Module,有CMakeLists.txt, nativejnilib.cpp, NativeLib三個檔案
nativejnilib.cpp: 實作C++的fun以及定義interface
CMakeLists.txt: 當有用到其他3th party library時可以在此檔案編輯編譯內容
NativeLib.kt : 提供給APP的接口
3. 此時,到 app的 build.gradle 新增剛剛的 module 作為相依並執行 gradle sync。
在app/MainActivity.kt 下加入以下code, 測試是不是可以抓到 JNI的訊息
package com.sqtek.createjni
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.sqtek.nativejnilib.NativeLib
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val test_API = NativeLib()
System.out.println(test_API.stringFromJNI())
val text = findViewById<TextView>(R.id.title)
text.text(test_API.stringFromJNI())
}
}
確認可以抓到
Hello from C++
4. 新增一個addTwoNum() API 處理兩個整數相加, 記得要將fun name改成完整的package name + class name
Java_com_sqtek_nativejnilib_NativeLib_XXXX()
nativejnilib.cpp
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_sqtek_nativejnilib_NativeLib_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
extern "C" JNIEXPORT jint JNICALL
Java_com_sqtek_nativejnilib_NativeLib_addTwoNum(
JNIEnv* env,
jobject, jint a, jint b) {
int sun = a + b;
return (jint) sun;
}
NativeLib.kt
package com.sqtek.nativejnilib
class NativeLib {
/**
* A native method that is implemented by the 'nativejnilib' native library,
* which is packaged with this application.
*/
external fun stringFromJNI(): String
external fun addTwoNum(a: Int, b: Int): Int
companion object {
// Used to load the 'nativejnilib' library on application startup.
init {
System.loadLibrary("nativejnilib")
}
}
}
5. 在app/MainActivity.kt 下加入以下code, 測試新的API addTwoNum()是不是會返回正確值
package com.sqtek.createjni
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.sqtek.nativejnilib.NativeLib
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val test_API = NativeLib()
System.out.println(test_API.stringFromJNI())
System.out.println(test_API.addTwoNum(10, 20))
}
}
6. 打包成 aar 給其他專案使用, 將nativejnilib把包成aar
上面的專案主要有兩個部份,一個是 app 擁有 Activity 來模擬使用這個lib的情況,令一個部份是 nativejnilib這個 module 為實際 lib 的內容,這是我們接下來要介紹的,如何將這個 module 轉成 aar。
首先,我們先點擊[Build]>[Select Build Varient]開啟選單,再生成 aar時可以選擇 debug 或是 release 來發布,這邊我選用 release 做示範。
設成 release 之後,再去[Build]>[Rebuild Project]讓專案建構一下,完成後會在 build 資料夾的 outputs 找到我們要的 aar。