Android Studio NDK開發-自定義庫

項目中的公共代碼或者公用模塊,常常使用庫的方式進行管理,除了第三方庫以外,開發中也常常自己定義一個庫。
在Android Studio使用Modules的方式讓一個庫的源代碼在多個項目中使用,這是gradle在管理Android項目中常用的方式之一,那NDK的library庫又是如何管理的呢?
gradle-experimental既然是gradle的擴展插件,必然有很多的地方和gradle類似,管理類庫也是采用類似的方式。

新建JNI類庫

當前的gradle-experimental還不支持直接新建jni module,因此需要需要手動的去新建JNI類庫。
首先把項目從Android切換到Project

project顯示項目

這樣項目文件就顯示為了樹狀結構:

樹狀

新建目錄jni-lib,在這個目錄下面新建文件bulid.gradle,這樣jni-lib目錄就是一個gradle的module了。
sttings.grable中把jni-libinclude進來

include :jni-lib

接下來就需要構建一個基于gradle-experimental的NDK的 module了。

com.android.model.native

插件com.android.model.native類似與com.android.library,是用來構建一個NDK類庫的DSL。
./jni-lib/build.gradle中添加代碼:

apply plugin: 'com.android.model.native'

model {
    android {
        compileSdkVersion = 23
        buildToolsVersion = '23.0.2'

        defaultConfig {
            minSdkVersion.apiLevel = 14
            targetSdkVersion.apiLevel = 23
            versionCode = 1
            versionName = '1.0'
        }

        ndk {
            moduleName = 'lib'
            abiFilters.addAll(['armeabi', 'armeabi-v7a']) //this is default
            ldLibs.addAll(['android', 'log'])
        }

    }

model.android.ndk中定義ndk的屬性:

model {
    android {
        ndk {
            moduleName = 'jni-lib'
            abiFilters.addAll(['armeabi', 'armeabi-v7a']) 
            ldLibs.addAll(['log'])
        }
    }
}

這里定義了類庫的名字為:jni-lib,支持的平臺armeabiarmeabi-v7a,調用系統的log庫。

JNI代碼

JNI代碼默認放在module的主目錄下的./src/main/jni中,按照這個結構新建JNI代碼目錄。
JNI的庫中需要定義.h文件,方便其他module直接引用,在./src/main/jni中新建llib.h文件

#include <android/log.h>

#define  LOG_TAG "jni-lib"
#define  LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)

extern  void  callMethodFromJniLib();

新建llib.c文件實現llib.h中定義的方法:

#include "llib.h"

extern void callMethodFromJniLib() {
    LOGD("call methon from jni lib");
}

引入jni-lib

調用jni-lib類庫的時候,首先需要把header文件都給暴露出來,這樣可以在其他的module中直接引用,modle.android.sources中指定需要暴露的文件:


model {
    android {
       ....
        sources {
            main {
                jni {
                    exportedHeaders {
                        srcDir "src/main/jni"
                    }
                }
            }
        }

    }
}

通過exportedHeaders這個DSL就可以塊中指定需要暴露的文件。

其他module中引用jni-lib的就比較簡單一些了,直接指定jni的依賴項即可,在model.android.sources.main.jni中指定依賴:


model {
    ....
    android {
       ...
        sources {
            main {
                jni {
                    dependencies{
                        library 'openssl' linkage 'static'
                        project ':jni-lib'
                    }
                   
                }
             }
        }

       ...

    }

}

jni.dependencies中指定了依賴project:jni-lib,linkage的默認值為shared
這樣就可以在app的jni中直接使用jni-lib中定義的方法了

#include <llib.h>

JNIEXPORT void JNICALL
Java_com_jjz_NativeUtil_callLogFromJni(JNIEnv *env, jclass type) {
    callMethodFromJniLib();//jni-lib中的方法
    __android_log_print(ANDROID_LOG_INFO, "jni-log", "from jni log");
    LOGW("log from  define");

}

源代碼地址:https://github.com/jjz/android/tree/master/experimental

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容