android studio編譯c生成.so檔案
今天練習了用studio編譯c生成.so檔案。
一、首先是配置NDK(以下是以我自己的路徑為例)
二、環境的搭建
設定ndk路徑
成功之後我們可以在local.properties檔案中看到:
之後還要在gradle.properties檔案中新增一行程式碼:android.useDeprecateNdk=true(否則會報錯)
三、JNI開發
環境都搭建好就可以進行java程式碼和C程式碼的編寫了。
首先先建一個java類JNIUtlils.java(我起名字的時候多了個l,忽略這個細節~)
注意:這個類裡面呼叫C的方法必須要用native宣告,而且方法名也要和C中的一樣;
System.loadLibrary("")引號中的是你要生成庫的名字,不加字尾.so
之後重新make project
在D:\Studio\Demo\JniTest\app\build\intermediates\classes\debug\com\xiezhong\jniTest中看到JNIUtlils.class
接下來生成.h標頭檔案。在studio的左下方可以找到Terminal,點開它
之後進入到build\intermediates\classes\debug目錄中去,執行javah -classpath . -jni com.xiezhong.jniTest.JNIUtlils命令(此處填你自己剛剛生成的class路徑)
執行後在debug目錄下就會生成一個.h檔案
在main中建立一個jni資料夾
將上面debug目錄下新生成的.h檔案剪下到jni資料夾中,再在jni裡建立一個.c檔案
(我的檔案為com_xiezhong_jniTest_JNIUtlils.c)
編輯內容如下:
#include "com_xiezhong_jniTest_JNIUtlils.h"
/**
* 上邊的引用標籤一定是.h的檔名加字尾,方法名一定要和.h檔案中的方法名稱一樣
*/
JNIEXPORT jstring JNICALL Java_com_xiezhong_jniTest_JNIUtlils_getString
(JNIEnv *env, jobject obj) {
return (*env)->NewStringUTF(env, "這是我測試的jni");
}
.c和.h檔案都完成了,接下來在jni中建立Android.mk和Application.mk檔案
首先Android.mk的內容:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := huazict
LOCAL_SRC_FILES := com_xiezhong_jniTest_JNIUtlils.c
include $(BUILD_SHARED_LIBRARY)
注意:LOCAL_MODULE是要編譯的庫的名字,編譯器會自動加上lib的字首和.so的字尾
LOCAL_SRC_FILES是要編譯的C/C++檔案
Application.mk內容:
APP_ABI := all
這些都完成後我們開始配置gradle:
注意:紅色橫線標記的一定要加上,因為jni每次執行都會在build\intermediates\ndk中自動編譯生成一個Android.mk檔案,這樣我們之前在jni中手動編譯的Android.mk就沒有作用了,然後就會報如下錯誤:
Warning:Deprecated NDK integration enabled by useDeprecatedNdk flag in gradle.properties will be removed from Android Gradle plugin soon.
Error:Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.process.ProcessException: Error while executing 'D:\ndk\android-ndk-r9d\ndk-build.cmd' with arguments {NDK_PROJECT_PATH=null APP_BUILD_SCRIPT=D:\Studio\Demo\JniTest\app\build\intermediates\ndk\debug\Android.mk
APP_PLATFORM=android-25 NDK_OUT=D:\Studio\Demo\JniTest\app\build\intermediates\ndk\debug\obj NDK_LIBS_OUT=D:\Studio\Demo\JniTest\app\build\intermediates\ndk\debug\lib APP_ABI=armeabi-v7a,armeabi,x86}
所以jni.srcDirs = [ ]一定要加上,這樣就不會自動編譯了,用的是我們自己的mk檔案。
最後我們在Terminal中進入到main目錄下執行ndk-build命令:
這樣我們的.so檔案就生成好了:
把libs中的.so都複製到外面的jniLibs資料夾中:
現在我們可以執行我們的程式了,結果如下圖:
希望對大家有所幫助~~