以前因爲工做緣由使用grails這個基於groovy的框架作項目,對groovy感受很好。java
基於groovy的gradle構建系統對我而言天然也是好的沒得說。android
Android Studio 正式版出來沒多久,不完善的地方天然不少,對於從eclipse轉來的夥伴們而言,不瞭解groovy的話對於gradle android的dsl天然是一頭霧水,其實groovy蠻好,花點時間學學,目前已經支持android開發了。app
最近乾的活設計到NDK開發,在編譯時遇到一些很差搞定的問題。框架
使用gradle編譯ndk後會發現,gradle實際上是本身按dsl生成了android.mk
,而後執行ndk-build
命令,仔細對比會發現,它沒有生成application.mk
。那麼問題來了,對於個人項目而言,使用gradle老是編譯不過去,而本身運行ndk-build
則不會出現問題。eclipse
構建系統原本就是解決了這種批處理問題,不想拋開gradle而手動去編譯,乾脆就讓gradle執行本身的ndkbuild Task。gradle
經過不斷試錯,整理以下Task:ui
// 編譯NDK代碼 task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') { // android.mk 地址 ,自行更改 def androidMK = "$projectDir/src/main/jni/Android.mk" // application.mk 地址, 自行更改 def applicationMK = "$projectDir/src/main/jni/Application.mk" def ndkDir = project.plugins.findPlugin('com.android.application').getNdkFolder() def cmd = ["$ndkDir/ndk-build", "NDK_PROJECT_PATH=$buildDir", "APP_BUILD_SCRIPT=$androidMK", "NDK_APPLICATION_MK=$applicationMK"] commandLine cmd } // 打包native庫, 會在編譯java代碼後執行 task ndkLibsToJar(type: Zip, dependsOn: ["compileDebugJava", ndkBuild], description: 'Create a JAR file of the native libs') { destinationDir new File(projectDir, 'libs') baseName 'ndk-libs' extension 'jar' from(new File(buildDir, 'libs')) { include '**/*.so' } into 'lib/' } dependencies { compile fileTree(dir: new File(projectDir, 'libs'), include: ['*.jar']) }
固然,首先要確保項目根目錄下 local.properties
中有ndk的目錄位置的設定 ndk.dir=/YOUR_NDK_FOLDER
spa
原本javah
的參數就麻煩,有其實classpath
的設定,還得指定包名,非常麻煩,若是包含native聲明方法的類中包含了android庫,不指定好android.jar就更麻煩。debug
// 生成jni頭文件,在編譯java後運行 task generateJNI(dependsOn: "compileDebugJava", description: 'Create jni header'){ //要生成的類名, 能夠多個 def classes = ["org.jcuraengine.JCuraEngine"] //jni生成到哪裏 def destdir = "$projectDir/src/main/jni/jcuraengine" // 獲取android jar def rootDir = project.rootDir def localProperties = new File(rootDir, "local.properties") Properties properties = new Properties() localProperties.withInputStream { instr -> properties.load(instr) } def sdkDir = properties.getProperty('sdk.dir') def androidJarPath = sdkDir + "/platforms/" + android.compileSdkVersion + "/android.jar" def classesName = "" classes.each{ classesName += " $it" } // 調用 javah try { // exec會出現錯誤,這裏使用ant // 第一次運行這個task時,會出現錯誤,是android studio致使的,運行兩次既可,忽視第一次執行時的異常 // 固然,注意觀察第一次的異常,確保不是代碼自身問題。 ant.javah(class: classesName, destdir: destdir, classpath:"$androidJarPath:$buildDir/intermediates/classes/debug/") } catch (def e) { println e } }
這兩個task,在android stuido右側gradle tasks
版面中會自動添加的。設計