1. 程式人生 > >Android Studio 2.2 ndk開發環境 gradle配置

Android Studio 2.2 ndk開發環境 gradle配置

AndroidStudio2.2中
對於ndk/jni 建議使用cmake進行編譯
而對於純粹的android程式設計師來說,cmake不是經常接觸的方案,我在遇到jni相關時也遇到了一些問題,這裡拋磚引玉吧

開發環境:

Android SDK/NDK
Android Studio 2.2
需要下載的SDK元件
友情提示:更新請科學上網

準備工作

其實demo永遠是最好的老師
我們直接自己建立一個Project
這裡一定要選中
好在AS對於對於ndk的支援越來越友好
選中c++支援,這樣創建出來的gradle檔案就會自動建立相關的,有助於我們學習

自動生成的核心檔案

build.gradle
MainActivity.java
native-lib.cpp
CMakelists.txt

MainActivity.java

MainActivity.java

    System.loadLibrary("native-lib"); //載入native-lib庫
    ...
     public native String stringFromJNI();//指向cpp檔案中的方法

指向cpp
左邊有一個箭頭,這個點選可以直接跳到cpp檔案中的方法

gradle

project級別的和傳統沒有差別
看module級的

apply plugin: 'com.android.application'

android {
    ...
        externalNativeBuild {
            cmake {
                cppFlags ""
} } } ... externalNativeBuild { cmake { path "CMakeLists.txt" } } ndk{ abiFilters 'armeabi' //打包的cpu方案 } } dependencies { ... }

看到核心差別就是這幾句
cppFlags 先不去管
這裡有一個path "CMakeLists.txt"
這個指向了一個txt檔案
開啟這個檔案

CmakeLists.txt

總體語法是 #為單行註釋

指定最低版本號
新增庫檔案
找到指定的庫
連線目標庫


通過觀察這裡有native-lib的地方就是指定的幾處

建立自己的library

接下來模仿這個語法來寫個自己的庫
在cpp資料夾下,新增一個
math-lib.cpp
math-lib.h

接著修改cmake

...

cmake_minimum_required(VERSION 3.4.1)#最低版本號

...

add_library( ...
             native-lib  #庫的名稱

            ...
             SHARED  #是否設定為共享庫

            ...
             src/main/cpp/native-lib.cpp #庫檔案的指向
             )

add_library(#這裡是我自定義的demo庫
            math-lib  
            SHARED
            src/main/cpp/math-lib.cpp
            src/main/cpp/math-lib.h
            )
...

find_library( # Sets the name of the path variable.
              log-lib
...
              log )

...

target_link_libraries( # Specifies the target library.
                        native-lib
                        math-lib
                      ...
                       ${log-lib} )

在native-lib的位置填寫自己的library名稱,和檔案位置
接著在MainActivity中寫一個native方法
private native int add(int a,int b);

在靜態程式碼塊中 載入庫
庫的名稱是math-lib

static{
     System.loadLibrary("math-lib");
 }

修改cpp檔案

#include <jni.h>
#include <string>

//
// Created by kikt on 2016/10/21.
//

#include "math-lib.h"
extern "C"
JNIEXPORT jint JNICALL
Java_com_kikt_ndkdemo1_MainActivity_add(JNIEnv *env, jobject instance, jint a, jint b) {
    return a+b;
}

這裡比較簡單,返回a+b的返回值就可以了

不會寫JNI的c方法名的朋友,AS現在已經可以通過提示自動生成的,好方便!

當然我們還是需要知道下如何自己生成,萬一哪天AS抽風了呢
這裡推薦一個我很久前看到的blog使用Javah 生成C/C++標頭檔案的誤區

這裡有一個特別要注意的地方,因為這個是cpp檔案 和c檔案不同的是 必須加上extern “C” 防止編譯器將方法改名,否則會造成natvie方法呼叫不到,丟擲異常

後記

會寫這個文章是因為頭一陣研究視訊編解碼的時候引入了一個第三方庫GPUImage的時候遇到了編譯不通過,無奈換回AS2.1的問題正常編譯執行的問題

因為AndroidStudio 2.2正式版剛剛開放載入一段時間,有一些朋友在ndk開發時可能會遇到各種問題,這裡僅做一個入門的參考
歡迎留言交流