Andorid Studio NDK开发-使用库

C语言是一个巨大的宝库,系统底层的很多的实现都是基于C语言实现的,比如图像处理,加密等。
C语言的运行效率也是很高的,因此为了效率有时候也会引入第三方的C语言库。
总而言之,会在NDK开发的过程中会使用大量的库,系统自带的库,第三方库等。
在gradle-experimental中使用C语言的库是非常便利的。

调用系统库

Log是在Android开发过程用来调试程序必备的工具之一,如何在NDK中使用android.util.Log方便在Logcat中查看JNI程序的运行情况呢?这就需要在NDK中导入Android系统的Log库。
首先需要在在gradle中引入Log库:

model{ .... android {        compileSdkVersion 23        buildToolsVersion "23.0.2"        ndk {            moduleName "experiment"                ldLibs.addAll([ 'log']);        }   } }

直接在ldLIbs中加入log就可以,如果需要引入其他的系统库,只要在数组中直接增加即可。
再定义一个native的方法:

public static native void callLogFromJni();

在Jni中调用Log库的方法:

//引入 log# include JNIEXPORT void JNICALLJava_com_jjz_NativeUtil_callLogFromJni(JNIEnv *env, jclass type) {    __android_log_print(ANDROID_LOG_INFO,"jni-log","from jni log");}

第一个参数,ANDROID_LOG_INFO是log的级别他包含:

typedef enum android_LogPriority {    ANDROID_LOG_UNKNOWN = 0,    ANDROID_LOG_DEFAULT,    /* only for SetMinPriority() */    ANDROID_LOG_VERBOSE,    ANDROID_LOG_DEBUG,    ANDROID_LOG_INFO,    ANDROID_LOG_WARN,    ANDROID_LOG_ERROR,    ANDROID_LOG_FATAL,    ANDROID_LOG_SILENT,     /* only for SetMinPriority(); must be last */} android_LogPriority;

一般我们常用的是ADNROID_LOG_VERBOSE,ANDROID_LOG_DEBUG,ANDROID_LOG_INFO,ANDROID_LOG_WARN,ANDROID_LOG_ERROR分别对应java中的Log.v,Log.d,Log.i,Log.w,Log.e。
第二个参数是tag,用来方便的对log分类。
第三个参数是message,对应log的具体信息。

一般还会采用宏定义的方式,定义Log的输出的方法,方便调用:

# define LOG_TAG "jni-log"# define LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)

这里定义了一个warning log的宏,在代码里面可以直接调用:

  LOGW("log from  define");

使用第三方类库

OpenSSL是最常用的加密库之一,下面以OpenSSL为例,介绍下在gradle-experimental中如何引入第三方类库。关于如何编译Android下的OpenSSL详见:编译Android的OpenSSL类库。
首先定义对于库的repositories:

model {   repositories{        libs(PrebuiltLibraries) {            // Configure one pre-built lib: static            openssl {                // 头文件地址                headers.srcDir "/usr/local/ssl/android-23/include"                // 静态链接库的引用,                binaries.withType(StaticLibraryBinary) {                    staticLibraryFile = file("libs/libcrypto.a")                }                //动态链接库的引用//                binaries.withType(SharedLibraryBinary) {//                    sharedLibraryFile = file("libs/libcrypto.so")//                }            }        }    }  }

c语言的类库分为静态链接库(.a)和动态链接库(.so),静态类库和动态类库的引入方式是不一样的,分为对应:StaticLibraryBinary和SharedLibraryBinary。这里引入的库为静态链接库,名称为:openssl.

指定库依赖:

model{ ...... android{  .....   sources {            main {                jni {                    dependencies{                        library 'openssl' linkage 'static'                        //动态链接库                        //  library 'openssl' linkage 'shared'                    }                    source {                        srcDir "src/main/jni"                    }                }                jniLibs{                    source{                        srcDir "libs/"                    }                }                java{                    source{                        srcDir "src/main/java"                    }                }            }        } }}

这里在model.android.sources.main中指定库的依赖为上面定义的openssl,linkage类型为static,如果是动态链接库linkage就是shared。
因为编译的OpenSSL只支持arm结构的cpu,因此需要指定abi为对应的cpu,在model.android添加配置:

 ndk {      moduleName "experiment"      abiFilters.addAll(['armeabi', 'armeabi-v7a'])           }

使用OpenSSL

首先定义一个native方法,需要从OpenSSL中读取随机数:

public static native byte[] getRandom();

生成对应的JNI方法:

//引入OpenSSL的rand# include JNIEXPORT jbyteArray JNICALLJava_com_jjz_NativeUtil_getRandom(JNIEnv *env, jclass type) {    unsigned char rand_str[128];    RAND_seed(rand_str, 32);    jbyteArray bytes = (*env)->NewByteArray(env, 128);    (*env)->SetByteArrayRegion(env, bytes, 0, 128, rand_str);    return bytes;}

RAND_seed是OpenSSL的方法,读取随机数。这段代码就是读取一个128的随机数,然后转换为java的byte[]。

在界面上面使用读取随机数的方法:

tv2.setText(Base64.encodeToString(NativeUtil.getRandom(), Base64.DEFAULT));

运行之后可以在界面看到一段随机的字符串显示:

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

关键字:android, openssl, ndk


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部