JNI Md5加密生成so文件

JNI Md5加密生成so文件

IDE工具:Android Studio
编译环境:JDK1.8+Android SDK+NDK

1 新建项目

选中“Include C++ support”,一直“Next”.

等待项目构建完成后

看到 java包同级有个cpp的包就是存放c++代码的。

而里native-lib.cpp的代码很简单,就是打印出一句“Hello from C++”:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <jni.h>
#include <string>

extern "C"
JNIEXPORT jstring

JNICALL
Java_sogrey_android_1jni_1md5_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}

运行一下:

这就表示我们的C++环境正常,可以开始写我们自己的代码了。

2 新建Jni工具类

新建一个JNIUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package sogrey.android_jni_md5;

/**
* Created by Sogrey on 2018/8/3.
*/

public class JNIUtils {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}

/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
}

MainActivity.java中的相关代码删掉

tv.setText(stringFromJNI());

也改成

tv.setText(new JNIUtils().stringFromJNI());

3 生成.h文件,编写cpp文件

Android studio的Terminal中依次执行命令:

cd app/src/main/java
javah -jni sogrey.android_jni_md5.JNIUtils

将生成的sogrey_android_jni_md5_JNIUtils.h头文件剪贴到cpp包下,并复制一份重命名为sogrey_android_jni_md5_JNIUtils.cpp.

编辑复制的.cpp文件,删掉多余代码只留下需要我们实现的那个方法,加上返回方法体,并导入之前的.h文件

1
2
3
4
5
6
7
8
9
#include "sogrey_android_jni_md5_JNIUtils.h"
/*
* Class: sogrey_android_jni_md5_JNIUtils
* Method: stringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_sogrey_android_1jni_1md5_JNIUtils_stringFromJNI
(JNIEnv *env, jobject obj){
}

方法需要返回jstring,可以参照之前native-lib.cpp里的代码实现,引入提示需要导入string:

1
#include <string>

则最终代码就是:

1
2
3
4
5
6
7
8
9
10
11
12
#include <string>
#include "sogrey_android_jni_md5_JNIUtils.h"
/*
* Class: sogrey_android_jni_md5_JNIUtils
* Method: stringFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_sogrey_android_1jni_1md5_JNIUtils_stringFromJNI
(JNIEnv *env, jobject obj){
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}

4 修改CMakeLists.txt文件

我们刚刚添加了一个新的c++文件,现将它加到CMakeLists中,刚才的native-lib.cpp已经没有用了,注掉它

重新编译运行看会不会得到和之前一样的结果。(结果是一样的)
build>intermediates>cmake>debug>obj下就能找到生成的.so文件了

5 添加getMd5(String)的native方法

JNIUtils.java中添加下面native方法:

1
2
3
4
5
6
/**
* 获取指定字符串md5值
* @param content 要md5加密的字符串
* @return md5加密串
*/
public native String getMd5(String content);

重复第三步操作。或者熟练了直接在sogrey_android_jni_md5_JNIUtils.h文件中添加:

1
2
3
4
5
6
7
/*
* Class: sogrey_android_jni_md5_JNIUtils
* Method: getMd5
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_sogrey_android_1jni_1md5_JNIUtils_getMd5
(JNIEnv *, jobject, jstring);

同样,需要在sogrey_android_jni_md5_JNIUtils.cpp中去实现它:

1
2
3
4
5
6
7
8
9
/*
* Class: sogrey_android_jni_md5_JNIUtils
* Method: getMd5
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_sogrey_android_1jni_1md5_JNIUtils_getMd5
(JNIEnv *env, jobject obj, jstring str){
//TODO 实现方法逻辑
}

6 实现MD5加密

md5的加密方法网上很多,这里给出一个c++实现的[MD5.cpp,MD5.h].直接将两个文件引入到cpp包下,
sogrey_android_jni_md5_JNIUtils.cpp引入

#include “MD5.h”

getMD5方法实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
* Class: sogrey_android_jni_md5_JNIUtils
* Method: getMd5
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_sogrey_android_1jni_1md5_JNIUtils_getMd5
(JNIEnv *env, jobject obj, jstring str) {
const char *originStr;
//将jstring转化成char *类型
originStr = env->GetStringUTFChars(str,JNI_FALSE);
MD5 md5 = MD5(originStr);
std::string md5Result = md5.hexdigest();
// //将char *类型转化成jstring返回给Java层
return env->NewStringUTF(md5Result.c_str());
}

其中:JNI_FALSE 是个宏定义表示 jboolean false

1
2
#define JNI_FALSE 0
#define JNI_TRUE 1

运行一把,得到md5字符串

7 生成.so文件

在cmake.txt中添加

#设置生成的so动态库最后输出的路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})

用来指定生成的so文件存储路径,点击build>Make project,看到在jniLibs文件夹下生成支持4中不同内核的so文件。

想要配置指定内核平台,修改Module下的build.gradle中的android>defaultConfig 添加:

1
2
3
4
5
6
7
externalNativeBuild {
cmake {
cppFlags ""
abiFilters "arm64-v8a","armeabi-v7a","x86","x86_64"
//Error:ABIs [armeabi] are not supported for platform. Supported ABIs are [armeabi-v7a, arm64-v8a, x86, x86_64].
}
}

8 修改库名称

默认生成的so库名称是native-lib,怎么修改为自定义的名称呢。

首先,修改CMakeLists.txt内容:修改add_librarytarget_link_libraries第一个参数为我们想自定定义的名称,比如md5Lib

同样需要修改JNIUtils.javaSystem.loadLibrary(String)的参数为上面我们自定义的名称md5Lib

重新点击build>Make project,看到在jniLibs文件夹下生成新的so文件。

项目源码地址github

文章目录
  1. 1 新建项目
  2. 2 新建Jni工具类
  3. 3 生成.h文件,编写cpp文件
  4. 4 修改CMakeLists.txt文件
  5. 5 添加getMd5(String)的native方法
  6. 6 实现MD5加密
  7. 7 生成.so文件
  8. 8 修改库名称
本站总访问量 | 本文总阅读量