1. 程式人生 > >android studio編譯c生成.so檔案

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資料夾中:


現在我們可以執行我們的程式了,結果如下圖:


希望對大家有所幫助~~