Andorid Studio NDK 開發 – NDK 開發利器 gradle-experimental

姜家志發表於2019-03-04

使用NDK開發有件比較麻煩的事情就是編寫Application.mkAndroid.mk的,而Android Studio 的外掛gradle-experimental就是用來解決這個這個問題的。使用gradle-experimental外掛可以不用再編寫*.mk檔案的情況下進行NDK開發。
gradle-experimental是Android Studio的一個實驗性的專案,是基於gradle的一個外掛,主要用來自動化NDK的配置實現,無需自己編寫Application.mkAndroid.mk,對於除錯NDK專案也更加的友好,支援對於NDK的Debug。
下面就來嘗試下gradle-experimental的便利吧!

##環境要求:

  • Android Studio > 2.0
  • gradle>2.10
  • Android NDK r10e
  • Build Tools > 19.0.0

##配置gradle-experimental

  • 新增gradle-experimental依賴
    在專案的主目錄下./build.gradle中替換掉以前的build tools,使用最新版本的gradle-experimental

    buildscript {
     repositories {
         jcenter()
     }
     dependencies {
         classpath "com.android.tools.build:gradle-experimental:0.7.0"
     }
    }複製程式碼
  • 替換外掛(plugin)
    使用gradle-experimental就不能再使用com.android.application了,需要使用com.android.model.application替代。
    在專案主目錄下的./app/build.gradle中更改plugin

    apply plugin: “com.android.model.application”

  • 配置model{}

增加model{},android的配置在model{}中。

   model {
          android {
        compileSdkVersion 23
        buildToolsVersion "25.0.0"
        ndk {
            moduleName "experiment"
            //stl = `gnustl_static`
            //toolchain = `clang`
            //todo 指定cpu
            abiFilters.addAll([`armeabi`, `armeabi-v7a`]) //this is default
            ldLibs.addAll([ `log`]);
        }
        defaultConfig {
            applicationId "com.jjz"
            //需要使用.apiLevel
            minSdkVersion.apiLevel 15
            targetSdkVersion.apiLevel 23
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
            }
        }
    }
}複製程式碼

##配置NDK
在配置NDK之前需要確認:

  • NDK包是否下載
  • NDK的環境變數是否配置

能夠正確執行命令:ndk-build

以上配置完成之後,在./app/build.gradle中配置要配置android.ndk的相關內容:

model {
    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.2"
        ndk{
             moduleName "experiment"
            //toolchain = `clang`
            abiFilters.addAll([`armeabi`, `armeabi-v7a`]) //this is default
            ldLibs.addAll([ `log`]);
        }

    }

}複製程式碼

這裡定義的moduleName就是後面生成的NDK的包名。我們還可以指定其編譯成對應的cpu,編譯工具,使用的類庫等。

##原始碼配置
預設情況下,在src/main/jni下使用的是c/c++檔案。也可以在model.android中指定:

model {
    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.2"
        ndk {
            moduleName "experiment"
        }
        sources {
             main {
                jni {
                    source {
                        srcDir "src/main/jni"
                    }
                }
                java{
                    source{
                        srcDir "src/main/java"
                    }
                }
            }
        }
    }
}複製程式碼

sources分別指定了java原始碼和jni原始碼的目錄。
以上的配置完成之後,就可以使用gradle experimental開始NDK開發了。

##使用gradle experimental
在java裡面定義一個native方法,native標識的方法會需要在jni中實現,可以在java中呼叫,還需要載入NDK生成的.so類庫。

public class NativeUtil {
    //載入類庫
    static {
        System.loadLibrary("experiment");
    }
    public static native String firstNative();
}複製程式碼

這個時候編譯器會出現一個紅色的警告,因為定義的native方法編譯器並沒有找到對應的實現:

Andorid Studio NDK 開發 – NDK 開發利器 gradle-experimental
編譯器警告沒有實現native方法

可以使用alt+enter鍵可以自動生成jni檔案:

Andorid Studio NDK 開發 – NDK 開發利器 gradle-experimental
生成jni檔案

注意這個時候生成直接的是experiment.c,沒有.h檔案,生成的jni檔案的內容:

**#include <jni.h>**
JNIEXPORT jstring JNICALL
Java_com_jjz_NativeUtil_firstNative(JNIEnv *env, jclass type) {
    // TODO
    return (*env)->NewStringUTF(env, returnValue);
}複製程式碼

自動生成的jni檔案並沒有具體的實現,需要修改jni檔案讓其返回一段測試內容:

>JNIEXPORT jstring JNICALL
Java_com_jjz_NativeUtil_firstNative(JNIEnv **env, jclass type) {
    char chars[] = "i am test";
    return (*env)->NewStringUTF(env, chars);
}複製程式碼

這樣就完成了一個JNI開發呼叫,定義了一個native方法,在.c檔案中對其進行了實現。如果沒有gradle experimental外掛的話,現在就需要使用ndk-build命令編譯成.so檔案,然後在執行Android專案,呼叫方法看下是否能夠呼叫成功,而現在有了gradle experimental就變的瞭如此簡單,下一步就需要直接執行就可以了,對!就是直接執行,省略了中間的ndk-build環節,就和編寫Java程式碼一樣,直接執行即可。

##直接執行
開啟Toolbar中的執行配置選單,可以看到:

Andorid Studio NDK 開發 – NDK 開發利器 gradle-experimental
app-native

除了app以外,多出了一個app-native的選單,這個選項可以直接編譯NDK原始碼之後再執行Android,這樣編寫完NDK之後可以執行了,不需要再進行ndk-build:
在Java中呼叫NativeUtil.firstNative,會得到jni中寫好的返回值:i am test,在這個例子中,我讓這個這欄位顯示在主頁面上。

可以看到使用gradle-experimental開發NDK,不需要再做複雜的配置,自動化native方法,不需要自定義.h標頭檔案,對開發更加友好。

文中原始碼地址:github.com/jjz/android…

·

相關文章