1.引言
之前面试一般3年+的工作岗位要求知道ndk开发,了解framwork,甚至是音视频的硬解码等等。最开始不明白这些东西,随着不断的学习发现。库opensl能处理这些。因此准备来一个系列性学习将opensl,opengl.opencv等全部都学习一遍。
2.正题
opensl es:是能实现c语言加密以及优化音视频等库。opengl:与3d绘制有关的库。通过使用这些库,我们直接调用已经实现好的方法。然后实现加密,音视频播放等功能。
最开始学习的时候:看了很多博客,发现要引用opensl库有俩个方法:
1,导入so文件;2,直接将opensl里面的库导入到jni文件下.(这种网上有人用,理论上可以)
2.1 windows 编译opensl 得到对应的so文件
opensl 的连接文件https://github.com/aluvalasuman/OpenSSL1.0.1cForAndroid
下载完毕之后打开如下图所示的文件:
crypto,ssl为.c文件。
include:里面都是与.c文件相对于的.h文件
在这里按照博客,将这些文件编译,会得到俩个动态库:以及一些头文件:libcrypto.so,libssl.so , include头文件。下载连接:传送门
2.2开始集成
将libcrypto.so 和libssl.so 导入到jni文件夹下。如下图所示:
app的build gradle文件如下(感觉即使不配置也没得关系):
externalNativeBuild {
cmake {
cppFlags "-fexceptions"
abiFilters 'armeabi' //设置支持的abi
arguments '-DANDROID_PLATFORM=android-13',
'-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
开始之前强烈建议看看如下文档
android abi介绍
android Cmake
ndk-build
之后将opensl的include头文件,放在jni 文件夹下
注意:Cmake编写错误可能导致一些莫名其妙的错误
在此推荐一个良作,搞了2天就是它解决了我大部分问题:android Cmake 配置
#项目的文件路径,后续路径都是相对于这个路径
set(Project F:/workspace/Cmake)
cmake_minimum_required(VERSION 3.4.1)
#引用第三方库的格式
add_library(crypto SHARED IMPORTED)
add_library(ssl SHARED IMPORTED)
#设置第三方so的文件路径 ${ANDROID_ABI}代表“armeabi”,"x86"的统称
set_target_properties(crypto PROPERTIES IMPORTED_LOCATION
${Project}/app/libs/${ANDROID_ABI}/libcrypto.so)
set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
${Project}/app/libs/${ANDROID_ABI}/libssl.so)
#引入第三方so的头文件
include_directories( ${Project}/app/src/main/jni/include )
#引入自己编写的c文件代码。多个的话就有多个add_library
add_library(md5 SHARED src/main/jni/testmd.c)
find_library(log-lib log )
#连接第三方库
target_link_libraries(md5 crypto ssl ${log-lib} )
2.3 编写自己的c语言。
C语言代码:
#include
#include
#include
#include
JNIEXPORT jstring JNICALL
Java_xinyi_com_cmake_MD5Activity_m5EnCode(JNIEnv *env, jobject instance, jstring c_) {
const char *data = (*env)->GetStringUTFChars(env, c_, 0);
MD5_CTX ctx;
unsigned char md[16];
char buf[33]={'/0'};
char tmp[3]={'/0'};
int i;
MD5_Init(&ctx);
MD5_Update(&ctx,data,strlen(data));
MD5_Final(md,&ctx);
for( i=0; i<16; i++ ){
sprintf(tmp,"%02X",md[i]);
strcat(buf,tmp);
}
char *dest_str; // 目标字符串
dest_str = (char *)malloc(sizeof(char) * (sizeof(buf) + 1));
strncpy(dest_str, buf, sizeof(buf));
return (*env)->NewStringUTF(env,dest_str);
}
以上的C语言是百度Copy的运行之后生成的md5.前面多一个0.正常的md5 长度是16或者32
我遇到的问题:
第一次引用opensl 的确是麻烦多多。现在记录下
1,在c++文件下。方法前面要使用extern "C".不然程序会报错
2,将opensl的对应的crypto,include,ssl文件直接放进jni中,发现.h的路径报错(这种方式应该可以,有些博客提到了)