win10下androidStudio1.5中NDK環境搭建/安裝/使用
作業系統是win10,開發使用的IDE工具是android Studio,用Android Studio進行NDK開發比Eclipse更加靈活方便,不需要再修改makefile檔案,也不需要像以前一樣下載Cygwin。我選擇直接在SDK manager中下載NDK,當然也可以直接在android.developer的NDK中按照步驟下載安裝NDK,具體網址見:
一、下載NDK
檢查AndroidStudio的版本,我使用的最新的1.5,好像1.3之後在Android 環境開發JNI程式搭建開發環境變得相對簡單了,可以使用新的Gradle構建工具配置NDK環境.
使用AS內建的SDK Manager下載NDK(我的電腦可以下載,但是有的好像說是被牆了還是什麼原因下不了),在SDK Tools下有一個androidNDK選項,一般是沒有打勾的,勾上再apply,或者在專案上右鍵開啟Project Structure,切到的SDK Location頁在的androidNDKLocation,有一個提示安裝,點選即可進行安裝。安裝好後,將安裝路徑複製在androidNDKLocation下。
二、設定好NDK後,開始設定Gradle。要修改的檔案有三個。(這裡面好多坑,出了幾個小問題,結果搞了一晚上)
主要分為以下三個步驟:
A、首先設定projectGradle:
將該檔案中的dependencies{}塊中的gradle替換為實驗性質的gradle:
classpath 'com.android.tools.build:gradle-experimental:0.4.0'
這裡選擇的0.4.0的gradle,後面的wrapper,要設定為gradle-2.8-all,具體的見第三步。
B、再設定moduleGradle,這個修改比較多,千萬看清楚:
apply plugin: 'com.android.model.application' model{ android { compileSdkVersion = 23 buildToolsVersion = "23.0.1" defaultConfig.with { applicationId = "com.example.vivien_shaw.ndktest" minSdkVersion.apiLevel = 15 targetSdkVersion.apiLevel = 23 versionCode = 1 versionName = "1.0" } tasks.withType(JavaCompile) { // 指定編譯JDK版本 sourceCompatibility = JavaVersion.VERSION_1_7 targetCompatibility = JavaVersion.VERSION_1_7 } } android.ndk { moduleName = "test" // ldLibs +="log" // abiFilters +="armeabi" // abiFilters +="armeabi-v7a" // abiFilters +="x86" cppFlags.add("-std=c++11") ldLibs.addAll(['android', 'log', 'OpenSLES']) stl = "gnustl_static" } android.buildTypes { release { minifyEnabled = false proguardFiles.add(file('proguard-android.txt')) //proguardFiles += file( 'proguard-rules.pro') } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:design:23.0.1' }
裡面註釋掉的內容就是我修改過的地方,分別說明一下:
在android.ndk中,註釋掉了所謂支援armeabi,armeabi-v7a,x86三個平臺這三條語句,而修改為android官方的ndk例項中module.gradle對應模組的語句。如果不修改就會報這個錯:
還有就是dependencies{}中的compile 'com.android.support:design:23.0.1' 這裡需要新增上這句話,而且後面的版本號要和前面的相同。
和自動生成的gradle相比,更改的有以下幾個地方:
1、第一行android.application中加入了module
2、除dependenceies以外的部分被module模組包裝了起來
3、defaultConfig{} 需要寫成defaultConfig.with{} 的形式
4、buildTypes 需要從android{} 中取出來,寫成android.buildTypes{}的形式
5、android{}中多出了tasks.withType(JavaCompile).(我也看到有的部落格裡面新增compileOptions.with
{},並且放在adroid{}外的這種方式,不知道行不行)
6、module{}中新增android.ndk{}模組
還要一些需要注意的地方:
1、所有值的設定都要寫成 xxx = yyyy的形式,比如: applicationId = "com.zyp.ndktest" (自動生成的gradle 則可能是: applicationId "com.zyp.ndktest" ),否則會爆這種錯誤:Error:Cause: org.gradle.api.internal.ExtensibleDynamicObject, 當出現此類錯誤,檢查是否都用了 “=”的方式。
2、自動生成的buildType也需要修改:proguardFiles += file('proguard-rules.pro'
)
3、minSdkVersion和targetSdkVersion 後都需要加上apiLevel
4、增加compileOptions.with{} 需要選擇JavaVersion.VERSION_1_7,否則會報這種錯誤:Bad class file magic or version
C、最後設定gradleWrapper:
將左邊的工程檢視調整到Project,在gradle->wrapper->grale-wrapper.properties檔案的最後設定:distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip,注意這裡如果在Project gradle中設定的是gradle-experimental:0.4.0,則這裡選擇gradle-2.8-all,如果是gradle-experimental:0.2.0,需要設定gradle-2.5-all,由於我這裡沒有2.5版本的gradle,所以我選擇了2.8。
最後按這個鍵確認三個檔案修改的正確,修改正確的話,將會在gradle中顯示BUILD SUCCESSFUL
三、增加JNI目錄
見下圖,回到project檢視,在main下新建一個JNI folder,如圖:
在main/java下新建一個Test類,內容如下:
package com.example.vivien_shaw.ndktest;
/**
* Created by vivien_shaw on 2016/3/11.
*/
public class Test {
static {
System.loadLibrary("test");
}
public native void test();
}
這時你就會發現test顯示為紅色的,將滑鼠放在上面,alt+enter鍵將會出現 Creat function java_com……等字樣的提示,點選自動在之前新建的jni下出現對應的.c檔案,檔案內容新增為:
JNIEXPORT void JNICALL
Java_com_example_vivien_1shaw_ndktest_Test_test(JNIEnv *env, jobject instance) {
// TODO
__android_log_write(ANDROID_LOG_ERROR,"TAG","TEST");
}
哦對了,我自己操作的時候在這裡出現了一個問題,當我按下alt+enter鍵之後,沒有出現creat function等字樣的提示,而是告訴我:cannot resolve corresponding jni function ,後來我發現是我前面的三個檔案配置出錯導致gradle不能同步,修改正確之後就好了。
使用命令列即可生成對應的H檔案,這裡我用的android studio下的terminal,當用cmd時生成不出來,具體原因還不清楚:
這裡我加了一句話,-classpath D:\learning_program\SDK\platforms/android-23\android.jar;..\..\build\intermediates\classes\debug 具體原因見此說明:http://www.th7.cn/Program/Android/201509/550864.shtml
之後會在jni目錄生成對應的標頭檔案,最後在mainActivicity中加入一下內容:
Test t=new Test();
t.test();
執行,就會看到logcat的內容: