用NDK调用Android手机自带的openssl库函数 系统运行库层 和Android runtime
来源:互联网 发布:深圳网络教育哪家最好 编辑:程序博客网 时间:2024/06/13 21:17
最近在做视频播放那块,ffmpeg的neon移植之后,
发现yuv2rgb的转码效率太低,所以打算在jni里面,
直接将ffmpeg解码之后的yuv数据输出到SoftwareRenderer之后显示,
省去了yuv2rgb的过程。但在jni中,发现需要用到安卓源码的库和头文件。
请问这个是怎么使用的?在编译安卓源代码之后,
怎么使用?不编译源代码,从手机里面把相应的so文件和头文件拷贝到jni目录下面,可行吗?谢谢。本人对安卓不太熟悉,请多指教。谢谢各位。
为了解答这个问题而写的一篇通用类博客
目标: 目前很多Android手机已经自带了openssl库, 即libssl.so, libcrypto.so, 以下示例实现了APK通过NDK调用openssl库函数PKCS5_PBKDF2_HMAC(密钥生成算法)
1) 在android工程中创建 jni目录2) 编辑AbcJni.java
package com.example;
public class AbcJni
{
public native byte[] hashKey(byte[] key, byte[] salt, int count);
static {
System.loadLibrary("abc-jni");
}
}
3) 编译成功(生成AbcJni.java, 例如在bin目录下), 利用AbcJni.class生成
javah -classpath bin/classes -d jni com.example.AbcJni
这样会在jni目录下生成一个com_example_AbcJni.h文件
4) 新建abc-jni.c文件, 实现上述的头文件函数
#include <string.h>
#include <jni.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
JNIEXPORT jbyteArray JNICALL Java_com_example_AbcJni_hashKey
(JNIEnv *env, jobject thiz, jbyteArray pass, jbyteArray salt, jint count)
{
jbyte* pJbytePass = (*env)->GetByteArrayElements(env, pass, NULL);
char* szBytePass = (char *)pJbytePass;
int iLenPass = (*env)->GetArrayLength(env, pass);
jbyte* pJbyteSalt = (*env)->GetByteArrayElements(env, salt, NULL);
char* szByteSalt = (char *)pJbyteSalt;
int iLenSalt = (*env)->GetArrayLength(env, salt);
int OUTSIZE = 64;
char buf[64];
memset( buf, 0, sizeof(buf) );
PKCS5_PBKDF2_HMAC(
szBytePass,
iLenPass,
szByteSalt,
iLenSalt,
count, EVP_sha512(), OUTSIZE, buf);
jbyteArray jarray = (*env)->NewByteArray(env, OUTSIZE);
(*env)->SetByteArrayRegion(env, jarray, 0, OUTSIZE,buf);
(*env)->ReleaseByteArrayElements(env, pass, pJbytePass, 0);
(*env)->ReleaseByteArrayElements(env, salt, pJbyteSalt, 0);
return jarray;
}
4) 编辑Android.mk, 文件, 内容如下:LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := abc-jni
LOCAL_SRC_FILES := abc-jni.c
LOCAL_LDLIBS := -lcrypto -lssl
include $(BUILD_SHARED_LIBRARY)
5) 下载一个最新的openssl源代码, 解压. 假如解压后目录为/my/src/openssl-1.0.1k/
注: Android的SDK/NDK目录并没有openssl相关的头文件及库文件, 所以我们需要从源码中获取头文件
6) 进入ndk中以下目录(我使用android 4.4, platform 19), 建立头文件目录的软链接
cd /opt/android-ndk/platforms/android-19/arch-arm/usr/include
ln -s /my/src/openssl-1.0.1k/include/openssl .
7) 从你的手机拷贝以下文件(在/system/lib, 需要root哦)到ndk的lib目录下:
例如, 我的手机如下:
[my]# pwd
/system/lib
[my]# ls -la libcrypto.so libssl.so
-rw-r--r-- root root 1249844 2013-02-09 03:36 libcrypto.so
-rw-r--r-- root root 224784 2013-02-09 03:36 libssl.so
ndk的目录是:
/opt/android-ndk/platforms/android-19/arch-arm/usr/lib
8) 回到你的android工程
cd jni
ndk-build
如果成功, 你会发现../libs目录多了一个子目录, 及libabc-jni.so文件
9) 最后你可以在你的Android java代码中调用AbcJni.java中的以下方法了:
byte[] hashKey(byte[] key, byte[] salt, int count);
0 0
- 用NDK调用Android手机自带的openssl库函数 系统运行库层 和Android runtime
- 用NDK调用Android手机自带的openssl库函数
- 调用Android手机自带的闪光灯
- Android 调用系统自带的电话和设置功能
- android 调用系统自带的控件
- android系统自带的程序调用
- android webview 运行时不调用系统自带浏览器
- Android 去除手机系统自带动画
- android 删除手机自带的系统应用
- 编译android自带的ndk示例
- android调用系统自带图片的疑问?
- Android调用系统自带的下载程序进行下载。
- 如何调用android系统自带的一些方法
- Android调用系统自带的联系人表单
- 调用Android系统自带的图片浏览器
- android系统如何调用自带的相机相册
- Android 调用系统自带的相机/拍照
- android调用系统自带的文件管理程序选择文件
- 按两次返回键退出应用程序
- Linux Scheduling Domains
- 自动装箱(Autoboxing)和自动拆箱(AutoUnboxing)
- python基本操作
- Ubuntu 14.04分辨率怎么只有800*600和1024*768?
- 用NDK调用Android手机自带的openssl库函数 系统运行库层 和Android runtime
- 如何写出优美的 C 代码
- R语言常用数学函数
- 处理对象:
- 使用SPRING中的线程池ThreadPoolTaskExecutor并且得到任务执行的结果
- 数据库系统概论(1)
- 特征处理(Feature Processing)
- 技术和职业的思考
- jquery根据td给相同tr下其他td赋值方法