Android create a JNI (aar file)

github

  1. 使用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。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

購物車