儘管Android Studio已經愈來愈流行了,但不少人仍是習慣於Eclipse或源碼環境下開發JNI應用。我的認爲使用Android Studio做NDK開發是必然趨勢,因此本文將簡單介紹如何在Android Studio上實現NDK開發。html
JNI 是Java Native Inteface的縮寫,是Java中定義的一種用於鏈接Java和C/C++接口的一種實現方式。java
NDK 是 Native Developmentit的縮寫,是Google在Android開發中提供的一套用於快速建立native工程的一個工具。
使用這個工具能夠很方便的編寫和調試JNI的代碼。android
NDK可從官網或AndroidDevTools(我的網站)下載。git
Gradle 是一個基於Apache Ant和Apache Maven概念的項目自動化建構工具。它使用一種基於Groovy的特定領域語言(DSL)來聲明項目設置。github
以往Android NDK開發須要在Eclipse或源碼環境下,創建並配置Android.mk和Application.mk,且還要經過java命令生成.h頭文件,才能編譯生成so庫。但在Android Studio中這些步驟都不須要,由於Gradle足夠強大,只需配置Gradle便可編譯生成so庫。api
在2015年5月的Google I/O大會上, Google宣佈Android Studio開始支持NDK開發,經過和JetBrains的合做,將Clion整合進了Android Studio 1.3,並免費支持NDK C++開發。app
同年7月,在Android Studio 1.3版本上添加了gradle-experimental
插件,該插件支持NDK開發和調試,且帶有代碼不全和重構等高級功能。工具
CAVEAT: Note that this plugin is a preview of the plugin for feedback on performance and NDK integration. The Gradle API for the new component model is not final, which means each plugin will only work with a specific version of Gradle.
Additionally, the DSL may also change.gradle
目前這個插件是預覽插件,並非正式的。意味着插件只能運行在特定的Gradle版本上。而且DSL(領域特定語言)也要改變。網站
一、Gradle-2.5或更高版本
二、Android Studio 1.3 RC1或更高版本
三、Android NDK r10e 或更高版本
四、Build Tools 19.0.0 或更高版本
每一個版本的experimental插件須要特定的Gradle版本
Plugin Version | Gradle Version |
---|---|
0.1.0 | 2.5 |
0.2.0 | 2.5 |
0.3.0-alpha3 | 2.6 |
0.4.0 | 2.8 |
0.6.0-alpha1 | 2.8 |
0.6.0-alpha5 | 2.10 |
0.7.0-alpha1 | 2.10 |
一、新建一個Android標準工程
二、按F4打開工程配置
三、使用experimental插件須要對如下三個文件作修改:
./build.gradle ./app/build.gradle ./gradle/wrapper/gradle-wrapper.properties
將distributionUrl改用gradle-2.10版本
distributionUrl=https\\://services.gradle.org/distributions/gradle-2.10-all.zip
使用com.android.tools.build:gradle-experimental
代替 com.android.tools.build:gradle
buildscript { repositories { jcenter() } dependencies { //classpath 'com.android.tools.build:gradle:2.0.0' classpath "com.android.tools.build:gradle-experimental:0.7.0-alpha4" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } }
這部分改動比較大,修改及註釋以下:
// 用com.android.model.application 代替 com.android.application apply plugin: 'com.android.model.application' // 將原來的配置用 model{}包起來 model { android { // 取值必須使用 「=」 形式 // 不然會報 「Error:Cause: org.gradle.api.internal.ExtensibleDynamicObject」 錯誤 compileSdkVersion = 23 buildToolsVersion = '23.0.2' defaultConfig { // 取值必須使用 「=」 形式 applicationId = "com.connorlin.jnitest" //這裏要注意是 xxSdkVersion.apiLevel // 不然會報 「Unable to load class com.android.build.gradle.managed.ProductFlavor_Impl」錯誤 minSdkVersion.apiLevel = 15 targetSdkVersion.apiLevel = 23 versionCode = 1 versionName = "1.0" } // 配置NDK ndk { // 生成so的名字,是必須的 moduleName ="JNITest" toolchain = 'clang' CFlags.add('-std=c99') // 添加依賴庫 ldLibs.addAll(['android','OpenSLES', 'log']) // 生成不一樣abi體系的so庫 abiFilters.addAll(['armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64', 'mips', 'mips64']) } buildTypes { release { minifyEnabled = false // 這裏注意:使用proguardFiles.add()方法 proguardFiles.add(file('proguard-rules.txt')) } } } }
四、在Java文件(這裏以JNIActivity爲例)中添加代碼
static { System.loadLibrary("JNITest"); } public native String testJni();
此時,native方法標紅,提示以下:
在testJni()
方法上按快捷鍵Alt + Enter
,出現以下提示
按回車,會自動在main目錄下生成jni文件夾,內含JniDemo.c:
#include <jni.h> JNIEXPORT jstring JNICALL Java_com_connorlin_jnitest_MainActivity_testJni(JNIEnv *env, jobject instance) { // TODO return (*env)->NewStringUTF(env, "returnValue"); }
你會發現,Android Studio已經爲咱們自動生成JNI方法了,你只須要再寫實現就能夠了。
至此,最簡單的NDK開發配置完畢。
既然預覽版com.android.tools.build:gradle-experimental
支持NDK,
那麼正式版com.android.tools.build:gradle
是否也能夠實現NDK開發呢?
通過實驗,答案是能夠的!
一、新建一個Android標準工程,並在工程設置中配置NDK路徑。
二、打開 app level 的 build.gradle, 配置NDK
ndk { moduleName "NdkJniDemo" //生成的so名字 abiFilters "armeabi", "armeabi-v7a", "x86" //輸出指定三種abi體系結構下的so庫,可忽略 }
而後點擊右上角Sync Now, 會有以下錯誤提示:
按提示,在 gradl.properties 文件里加上android.useDeprecatedNdk=true
便可。
三、在Java文件(這裏以JNIActivity爲例)中添加代碼
static { System.loadLibrary("JNITest"); } public native String testJni();
接着在testJni()
方法上按快捷鍵Alt + Enter
並回車,
一樣,會自動在main目錄下生成jni文件夾,內含JniDemo.c:
#include <jni.h>
可是,你會發現並不會自動生成JNI方法,這是由於使用experimental插件纔會自動生成代碼。
那自動生成代碼該如何實現呢?
方法依然是使用gradle-experimental
插件,可是不一樣的是,在app level的build.gradle中添加com.android.tools.build:gradle-experimental
依賴。
四、在./app/build.gradle中添加gradle-experimental
依賴
dependencies { compile 'com.android.tools.build:gradle-experimental:0.7.0' }
再次在testJni()
方法上按快捷鍵Alt + Enter
並回車
#include <jni.h> JNIEXPORT jstring JNICALL Java_com_connorlin_jnitest_MainActivity_testJni(JNIEnv *env, jobject instance) { // TODO return (*env)->NewStringUTF(env, "returnValue"); }
你會發現成功自動生成JNI方法了。
這種方式有個反作用是 Run app 時可能會報錯:
此時,只要將gradle-experimental
依賴註釋掉便可正常運行,同時會保持自動生成代碼的功能,直到關閉工程。
這樣咱們在須要自動生成代碼的時候,將gradle-experimental依賴再次打開便可。
默認狀況下是不支持NDK調試的,但要支持NDK調試也很簡單,只要作些簡單配置便可。
一、打開JNI調試
二、配置Android Native - Debugger
三、下載LLDB 2.0
首次底部會報錯
點擊 Fix,提示下載LLDB 2.0,照作,下載安裝便可。
四、完成NDK調試配置,能夠正常調試了。
文/ConnorLin(簡書做者) 原文連接:http://www.jianshu.com/p/2690c9964110 著做權歸做者全部,轉載請聯繫做者得到受權,並標註「簡書做者」。