AndroidStudio編寫JNI程序

推薦一篇文章:
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']
        }
    }
}

當然,上面的方法,執行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']

        }
    }
 }
發佈了57 篇原創文章 · 獲贊 21 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章