推薦一篇文章:
http://blog.csdn.net/yanbober/article/details/51027520
這會是一個個人調研及嘗試的整理。因爲公司在用eclipse+cdt編寫jni,本人實在用慣了as,所以總結一些as編寫jni的方法。
1、NDK-build,老版本gradle
android studio編寫NDK也是發展了幾個版本,所以網上也會查詢到多種多樣的歷史方式。一開始是用cygwin,然後採用ndk中的工具鏈ndk build。
android studio默認so位置是jniLibs文件夾中,可以通過gradle設置。進入android.mk所在目錄,執行ndk-build後默認會編譯在Libs文件夾中,從而導致so庫找不到,這個需要注意。
後來,也可以通過gradle設置來自動使用ndk編譯:
android {
defaultConfig {
//設置NDK的模塊名稱及平臺
ndk{
moduleName "hello-jni"
abiFilters "armeabi"
}
}
//設置本地代碼,[]內容去掉則禁止AS的NDK自動編譯。
sourceSets{
main{
jni.srcDirs = ['src/main/jni']
}
}
}
2、最新版本gradle,link C/C++!
當然,上面的方法,執行ndk build編寫gradle都已經過時了!採用最新版本的gradle 2.2.2,不需要再進行上面的步驟!
首先,先看一種新手經常碰到的問題,as中C++代碼錯誤:
代碼多出標紅,沒有自動提示,是不是很抓狂。這個問題,也困擾本人好久,今天居然又去查閱了下as官方文檔,發現已經支持C++了啊,但是沒有找到具體配置。於是自己各種點點點居然試出來了。
其實就是頭文件沒有鏈接上,今天偶然發現解決方法:
本人是給as更新到2.2.2,gradle使用2.14就是最新吧記不清了。點擊file,選擇Linked C++:
然後選擇Jni中的Android.mk文件。
ok,頭文件連接上了,也有自動提示了,可以開發了!
程序編寫完成,不需要ndk build,直接運行程序,會自動編譯打包so文件。
如圖代碼中不再有jniLibs文件夾
但是編譯打包安裝apk後,可以在build文件夾下找到編譯好的so庫。
綜上所述,利用as編寫JNI程序,可以採用最新版本的gradle,然後link上我們的android.mk,這樣ndk build之類的操作都可以省略了,as可以幫我們編譯出so文件。
3.在Native方法中Log。
我們無法直接使用printf在android studio的logcat進行日誌打印。爲了做到這個,需要新建一個頭文件:
#include <Android/log.h>
#ifndef BRUSHVIEWDEMO_LOG_UTIL_H
#define BRUSHVIEWDEMO_LOG_UTIL_H
#define LOG "brush_demo_jni"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG,__VA_ARGS__)
#endif //BRUSHVIEWDEMO_LOG_UTIL_H
在要Log的地方引入這個頭文件,調用LOGE方法就可以在Logcat中打出本地方法中的日誌。使用方法:
LOGE(“float arr:%d,%d”,(int)res_arr[0],(int)res_arr[1]);
在LOGE中類似printf一樣,輸出你想打印的內容。
4.常用配置
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := 模塊名字
LOCAL_C_INCLUDES+= $(LOCAL_PATH)
SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
SRC_FILES := $(SRC_FILES:$(LOCAL_PATH)/%=%)
LOCAL_SRC_FILES := $(SRC_FILES)
#LOCAL_LDLIBS := -llog -landroid
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
自動編譯jni中全部cpp,比較方便。
Application.mk:
#APP_STL := gnustl_static
APP_STL := stlport_static
APP_ABI := armeabi-v7a
使用gradle編譯,在app.gradle中:
android {
sourceSets {
main {
//注意下面兩行命令順序不可以顛倒,不然會先加載so庫然後又自動編譯。
//禁止自動編譯
jni.srcDirs = [] //disable automatic ndk-build
//指定jniLibs的位置
jniLibs.srcDirs = ['native-libs']
}
}
}