Android studio NDK開發支持CMake和ndk-build兩種編譯方式:
第一種:CMake編譯方式的開發步驟
- 下載安裝studio 下載地址:“http://www.android-studio.org/”
- 新建項目
- 下載安裝ndk插件:File右鍵->setting->Android SDK->SDK Tool勾選CMake,LLDB,NDK,將這三個插件全都安裝上。
- 查看是否關聯上NDK,也可以手動添加(local.properties末尾加上如下代碼)
//這是自己的ndk地址,注意轉義,下面的地址本來是"E:\Android\SDK\ndk-bundle" ndk.dir=E\:\\Android\\sdk\\ndk-bundle
- gradle.properties文件末尾添加代碼"android.useDeprecatedNdk=true"(爲了適配低版本)
- 在module(如app:)目錄下創建一個CMake的配置文件(CMakeLists.txt,必須是這個名字,這個文件是用於關聯上gradle和CMake的),必須配置以下幾個基本屬性,如有需要並熟悉CMake語法,可自行酌情增加,可參考下面CMakeLists.txt的配置。(也可以在創建項目的時候勾選上support c++,studio就會自動創建該文件,並配置好gradle,並且會在MainActivity中生成一個native方法,創建一個cpp文件,和一個native-lib.cpp文件。這時候只需要去修改CMakeLists.txt中的參數,並且刪除cpp中自動生成的cpp文件,改成自己想要的就行。
#CMakeLists.txt配置內容如下 #版本 cmake_minimum_required(VERSION 3.4.1) add_library( # 決定編譯出來的so庫的名稱(這個配置文件得到的是libhello.so). hello # 動態 這樣studio會將so庫打包到你的apk中 SHARED #c文件的地址,若有多個文件,直接一一列出,以空格或者換行隔開 src/main/cpp/hello.c src/main/cpp/test.c) find_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log ) target_link_libraries( # Specifies the target library. hello # Links the target library to the log library # included in the NDK. ${log-lib} )
- 關聯CMake和gradle,配置這個的主要原因是爲了讓studio在編譯的時候能找到你的資源文。
有兩種方式:有的同學不一定Link C++ Project with Gradle選項,就用第二種
(1)自動關聯,將工程改爲Android視圖,右鍵選中module(如app),選擇Link C++ Project with Gradle,下拉選項中選擇CMake,瀏覽找到你的項目中的CMakeLists.txt文件。(2.)手動關聯,在module(如app)下的build.gradle中做如下配置externalNativeBuild屬性android { compileSdkVersion 25 buildToolsVersion "25.0.0" defaultConfig { applicationId "com.picovr.ndksupporttest" minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" externalNativeBuild { cmake { cppFlags "-frtti -fexceptions" } } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } externalNativeBuild { cmake { path "CMakeLists.txt" } } }
- 創建一個java類,在裏面申明一個native方法
package com.picovr.ndksupporttest.mynative; /** * Created by PICO-USER Dragon on 2017/1/17. */ public class JNI { public static native String getString(); }
- 創建.c或者cpp源文件,和頭文件。(下面以c語言爲例)
第一種方式:
在mian目錄下新建cpp文件夾。
選中Android Studio的左下角Terminal面板,輸入命令“cd app/src/main/java”進入java目錄,執行命令“javah 包名+類名“,這個命令是調用jdk中的javah.exe程序對native方法所在的Java類生成一個對應的.h頭文件。這種方式生成的.h頭文件中,自動將native方法在C語言中所對應的方法名全部生成出來了。然後將生成的.h文件剪切到cpp文件夾,並將.h文件中放方法名稱copy到c文件中,將參數補全即可。
生成.h文件的命令如:“javah com.picovr.ndksupporttest.mynative.JNI”
第二種方式:
在main目錄新建文件夾cpp,右鍵新建C/C++ Source File 勾選上Create an asscoiated hearder,這樣就會生成一個.c文件和.h的頭文件,這個.h文件不會像第一種方式那樣自動生成native方法在C語言中所對應的方法名,需要自己手動去寫。在學習階段建議手動去做,更好地瞭解並熟悉jni的一些規則。
java中的native方法對應C語言中的方法的規則在下面的代碼中已經詳細解釋:
copy下面的代碼的時候,導包hello.h和jni.h分別copy,因爲每個人的頭文件名字不一樣。ndk安裝路徑也不一樣,所以jni.h所在目錄不一樣。/* Created by PICO-USER Dragon on 2017/1/17. 導包的時候要注意 1.你自己創建的.h文件必須要 2.jni.h必須要,這個導包的時候,studio應該會提示,其實就是你安裝ndk所在目錄下的platforms目錄中的任意 一個版本中,可以在電腦中按照下面jni.h的那個路徑中找來看看 */ #include "hello.h" #include "../../../../../../Android/SDK/ndk-bundle/platforms/android-21/arch-x86_64/usr/include/jni.h" #include <stdio.h> #include <stdlib.h> /** * 命名規則:返回值類型 + 方法名 * 方法名:Java+包名+類名+方法名,並且把'.'改爲'_' * * JNIEXPORT和JNICALL 可要可不要string Java_com_picovr_ndksupporttest_mynative_JNI_getString(JN *IEnv *env, jobject jobj)也行 * * jstring 是返回值對應java中的String類 * JNIEnv *env 必須參數,在C中必須要用到這個參數去調用方法 * jobject jobj 必須參數 不一定用到 */ JNIEXPORT jstring JNICALL Java_com_picovr_ndksupporttest_mynative_JNI_getString(JNIEnv *env, jobject jobj) { //jstring (*NewStringUTF)(JNIEnv*, const char*);其實是在調用ndk-build中的jni.h中的方法 return (*env)->NewStringUTF(env, "The first jinDemo for Dragon !"); }
- 加載動態鏈接庫
在native方法所在類中增加靜態代碼塊,加載動態鏈接庫package com.picovr.ndksupporttest.mynative; /** * Created by PICO-USER on 2017/1/17. */ public class JNI { // Used to load the 'native-lib' library on application startup. static { //"hello"是so庫的名字,也就是CMakeLists.txt文件中add_library()屬性中的第一個參數 System.loadLibrary("hello"); } public static native String getString(); }
- 調用native方法getstring()。看看是否能成功調用。