最近在搞一個android上控制LED燈閃爍的功能,用到了串口編程,搜索了一下,發現Google發布了一個demo,android-serialport-api。有現成的代碼和APK,要想自己改JNI也比較簡單,就一個C文件。我把代碼下載后,想在android studio下重新編一個so,在此記錄一下。
一、環境准備:NDK(針對windows機器)
android SDK已經自帶ndk-bundle了,對應的目錄就是Android/sdk/ndk-bundle。先確保ndk-build命令能運行,打開CMD窗口,如果能看到以下內容,說明已經配置成功。
如果提示“不是內部命令或外部命令”之類的,那是環境變量沒配好。
添加一個系統變量,指向本地ndk目錄。
把新加的變量名加到Path路徑后面即可。
二、生成頭文件
當然可以通過命令行的方式,javah -jni 之類的,但是android studio已經簡化這個工作了,配置一下,只需要右鍵生成.h文件即可。請看下面。
配置工作本質上也是調用javah命令。打開android studio的設置窗口,選擇External Tools -> 新建(那個綠色+號)
填上以下內容。點擊右邊的Insert Macros有驚喜哦^^
為了后面在android studio直接運行ndk-build命令,此處也配置一個
好了,萬事俱備,只差怎么生成JNI層的h文件了。
寫一個包含native方法的Java,比如這樣的:
非常簡單,兩個方法,位於android.serialport.api這個包下。下面要做的就是把它轉成對應的h文件。
剛才添加的External Tools發揮作用了,只需要右鍵這個Java文件,執行javah即可。
接下來要做的就是把這個h文件拷到jni目錄下,在這個目錄再創建對應的實現文件C或者C++即可。
三、配置Android.mk和Application.mk文件
這兩個配置文件,定義了輸出so前的一些准備工作。Application.mk可以定義得很簡單,如下:
APP_ABI := armeabi armeabi-v7a x86
意思是輸出armeabi, armeabi-v7a, x86三種架構的so,如果只需要v7a,把其它兩個刪掉即可。Android.mk內容多了一點點。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := serial_port
LOCAL_SRC_FILES := android_serialport_api_JavaNdk.c
include $(BUILD_SHARED_LIBRARY)
前面兩行和最后一行是固定的。LOCAL_PATH是定義的開始,用於查找源文件,至於怎么找不用管。my-dir由Build System提供,返回包含Android.mk的目錄路徑。CLEAR_VARS也是類似,指向一個Makefile。BUILD_SHARED_LIBRARY表示編譯的是動態庫。更多定義請參考android官方描述:Android.mk
serial_port就是要輸出的so名字,當然最終會是libserial_port.so。LOCAL_SRC_FILES指向要編譯的源文件。
四、生成so
只要前面都配置好,源代碼也寫好,最后一步就是生成so庫了。在android studio中,jni目錄中里面有Android.mk, Application.mk, h文件, h文件對應的C或C++文件,只需要在jni這個目錄右鍵一下,選擇ndk-build命令即可(上面配置的)。那么,在你的項目中就會成功輸出so庫了。會在項目根目錄生成一個obj目錄,里面就存放着生成的so。
如果之前生成出錯,記得把obj目錄清空一下,把錯誤解決后重新ndk-build。