一、概述
学习jni开发有一段时间了,现在利用周末时间学习下要学习下C语法,这篇文章,主要以文件加解密讲解一下用eclipse进行NDK的开发流程。
一般开发经历的几个流程,我截个图(这个流程不包括环境配置):
二、开发步骤
2.1编写Java层Native方法
public class Cryptor {
public native static void crypt(String normal_path,String crypt_path);
public native static void decrypt(String crypt_path,String decrypt_path);
}
此类对应于一个加密方法和解密方法。
2.2javah命令生成头文件
cmd命令打开控制台,进入当前项目的src目录,执行Javah命令
此时刷新项目,在src目录下面就会出现头文件:
2.3创建jni目录
创建jni目录,将头文件引入进来
2.4添加本地支持add native support
添加ndk路径
2.5实现头文件中定义的函数
当添加本地支持后,会自动生成.c和.mk文件
然后在c文件中实现头文件中的函数
代码如下:
#include "com_wzc_ndkfilecrypt_Cryptor.h"
#include "stdio.h"
char password[] = "mynameislcty888";
//加密
JNIEXPORT void JNICALL Java_com_wzc_ndkfilecrypt_Cryptor_crypt
(JNIEnv *env, jclass jcls, jstring normal_path_jstr,jstring crypt_path_jstr){
//jstring -> char*
const char* normal_path = (*env)->GetStringUTFChars(env,normal_path_jstr,JNI_FALSE);
const char* crypt_path = (*env)->GetStringUTFChars(env,crypt_path_jstr,JNI_FALSE);
//打开文件
FILE *normal_fp = fopen(normal_path, "rb");
FILE *crypt_fp = fopen(crypt_path, "wb");
//一次读取一个字符
int ch;
int i = 0; //循环使用密码中的字母进行异或运算
int pwd_len = strlen(password); //密码的长度
while ((ch = fgetc(normal_fp)) != EOF) { //End of File
//写入(异或运算)
fputc(ch ^ password[i % pwd_len], crypt_fp);
i++;
}
//关闭
fclose(crypt_fp);
fclose(normal_fp);
}
//解密
JNIEXPORT void JNICALL Java_com_wzc_ndkfilecrypt_Cryptor_decrypt
(JNIEnv *env, jclass jcls, jstring crypt_path_jstr, jstring decrypt_path_jstr){
const char* crypt_path = (*env)->GetStringUTFChars(env,crypt_path_jstr,JNI_FALSE);
const char* decrypt_path = (*env)->GetStringUTFChars(env,decrypt_path_jstr,JNI_FALSE);
//打开文件
FILE *normal_fp = fopen(crypt_path, "rb");
FILE *crypt_fp = fopen(decrypt_path, "wb");
//一次读取一个字符
int ch;
int i = 0; //循环使用密码中的字母进行异或运算
int pwd_len = strlen(password); //密码的长度
while ((ch = fgetc(normal_fp)) != EOF) { //End of File
//写入(异或运算)
fputc(ch ^ password[i % pwd_len], crypt_fp);
i++;
}
//关闭
fclose(crypt_fp);
fclose(normal_fp);
}
c文件中实现文件加解密方法
2.6.编译生成.so动态库
build项目,自动生成.so文件
2.7.加载动态库
在工具类Cryptor编写加载动态库代码,在MainActivity中的点击事件中进行调用
具体代码如下:
加载动态库
public class Cryptor {
public native static void crypt(String normal_path,String crypt_path);
public native static void decrypt(String crypt_path,String decrypt_path);
static{
System.loadLibrary("ndk_file_crypt");
}
}
mainActivity中的代码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 加密
* @param view
*/
public void mCrypt(View view){
String normal_path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separatorChar + "liuyan.png";
String crypt_path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separatorChar + "liuyan_crypt.png";
Cryptor.crypt(normal_path, crypt_path);
Log.d("wzc", "加密完成");
}
/**
* 解密
* @param view
*/
public void mDeCrypt(View view){
String crypt_path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separatorChar + "liuyan_crypt.png";
String decrypt_path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separatorChar + "liuyan_decrypt.png";
Cryptor.decrypt(crypt_path, decrypt_path);
Log.d("wzc", "解密完成");
}
就是一个加密按钮和一个加密按钮的点击事件的实现,对sd卡根目录的图片进行加解密。xml布局我就不贴出来了。
日志打印结果:
三、总结
整个流程走完,我们就完成了在eclipse下用c代码对图片进行加解密的操作。
网友评论