Android JNI调用c语言加密程序
2018-01-07 16:46
381 查看
在这篇博客中,我将利用NDK调用JNI来使用本地c语言实现的一个简单的加密程序,主要是为了熟悉NDK和JNI的使用方法,希望可以让后来人少踩一些坑。
jdk1.8.0
android-ndk-r14b-windows-x86_64
在Android Studio中File–>ProjectStructure–>SDK Location配置“Android NDK Location”如下图:
修改app–>build.gradle,添加以下内容:
在defaultConfig中添加ndk项,这里moduleName是将来生成.so文件的名字,abiFilters是生成指定平台的so文件,如果不写abiFilters会生成所有平台的so文件
在buildTypes中添加sourceSets项,配置so文件存放位置
这里我们添加两个方法供以后使用,注意这里loadLibrary要和build.gradle中moduleName一致
输入命令javah -jni 包名.类名
生成的com_example_administrator_ndk_crypto_Crypto.h如下:
New–>Forder–>JNI Forder
2、将刚生成的.h文件复制到jni文件夹中
3、创建Crypto.c文件,引入头文件,并实现其中的方法。
4、创建Android.mk文件
LOCAL_SRC_FILES为c文件名,LOCAL_MODULE为so文件,应该与moduleName一致
5、创建Application.mk文件
APP_ABI := armeabi表示只支持armeabi架构的jni,如需其他架构可在后面追加
在main/libs中会生成.so文件
在main目录下新建一个jniLibs文件夹,将libs下面的文件复制到jniLibs中,编译运行即可。
https://github.com/Caesar233/Android-NDK-Crypto
系统环境:
Android Studio 2.3.3jdk1.8.0
android-ndk-r14b-windows-x86_64
配置NDK环境
下载NDK和配置环境变量在此不做赘述,不会的可以自行百度在Android Studio中File–>ProjectStructure–>SDK Location配置“Android NDK Location”如下图:
配置gradle.properties和build.gradle文件
在项目目录下gradle.properties文件中加入android.useDeprecatedNdk=true
修改app–>build.gradle,添加以下内容:
在defaultConfig中添加ndk项,这里moduleName是将来生成.so文件的名字,abiFilters是生成指定平台的so文件,如果不写abiFilters会生成所有平台的so文件
ndk { moduleName "Crypto" abiFilters "armeabi" }
在buildTypes中添加sourceSets项,配置so文件存放位置
sourceSets { main { jni.srcDirs = ['libs'] } }
添加native方法
public class Crypto { static { System.loadLibrary("Crypto"); } public native String encrypt(String prim); public native String decrypt(String code); }
这里我们添加两个方法供以后使用,注意这里loadLibrary要和build.gradle中moduleName一致
使用javah生成对应.h头文件
在Android Studio下方Terminal进入java路径(直接将文件夹拖到命令行就进入该目录了),如果没有Terminal,从View–>Tool Windows–>Terminal打开即可。输入命令javah -jni 包名.类名
javah -jni com.example.administrator.ndk_crypto.Crypto
生成的com_example_administrator_ndk_crypto_Crypto.h如下:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_example_administrator_ndk_crypto_Crypto */ #ifndef _Included_com_example_administrator_ndk_crypto_Crypto #define _Included_com_example_administrator_ndk_crypto_Crypto #ifdef __cplusplus extern "C" { #endif /* * Class: com_example_administrator_ndk_crypto_Crypto * Method: encrypt * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_example_administrator_ndk_1crypto_Crypto_encrypt (JNIEnv *, jobject, jstring); /* * Class: com_example_administrator_ndk_crypto_Crypto * Method: decrypt * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_example_administrator_ndk_1crypto_Crypto_decrypt (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif
创建jni目录和.mk文件
1、在main目录下新建jni目录:New–>Forder–>JNI Forder
2、将刚生成的.h文件复制到jni文件夹中
3、创建Crypto.c文件,引入头文件,并实现其中的方法。
#include "com_example_administrator_ndk_crypto_Crypto.h" JNIEXPORT jstring JNICALL Java_com_example_administrator_ndk_1crypto_Crypto_encrypt (JNIEnv * env, jobject obj, jstring str) { char *prim = (*env)->GetStringUTFChars(env, str, 0); char code[100]; int i,n,len; char temp_char,trans_char; int temp_num,trans_num; len = strlen(prim); for (int i = 0; i < len; ++i) { code[i] = prim[i] + 1; } for(i = 0;i < len;i++) { temp_char = prim[i]; //Consider about the corresponding number of character if (temp_char <= 'z' && temp_char >= 'a') temp_num = temp_char - 'a' + 1; else if (temp_char <= 'Z' && temp_char >= 'A') temp_num = temp_char - 'A' + 27; trans_num = temp_num*3 % 52; if (trans_num > 26 && trans_num <= 52) //Transform number to character trans_char = 'A' + trans_num - 27; else if (trans_num > 0 && trans_num <= 26) trans_char = 'a' + trans_num - 1; code[i] = trans_char; } code[len] = '\0'; return (*env)->NewStringUTF(env, code); } JNIEXPORT jstring JNICALL Java_com_example_administrator_ndk_1crypto_Crypto_decrypt (JNIEnv * env, jobject obj, jstring str) { char *code = (*env)->GetStringUTFChars(env, str, 0); char prim[100]; int i,n,len; char temp_char,trans_char; int temp_num,trans_num; len = strlen(code); for(i = 0;i < len;i++) { temp_char = code[i]; //Consider about the corresponding digit of character if (temp_char <= 'z' && temp_char >= 'a') temp_num = temp_char - 'a' + 1; else if (temp_char <= 'Z' && temp_char >= 'A') temp_num = temp_char - 'A' + 27; n = temp_num % 3; //Mode 3 and compute primitive number switch(n) { case 0: trans_num = temp_num/3; break; case 1: trans_num = 35 + temp_num/3; break; case 2: trans_num = 18 + temp_num/3; break; default: break; } //Transform number to character if (trans_num > 26 && trans_num <= 52) trans_char = 'A' + trans_num - 27; else if (trans_num > 0 && trans_num <= 26) trans_char = 'a' + trans_num - 1; prim[i] = trans_char; } prim[len] = '\0'; return (*env)->NewStringUTF(env, prim); }
4、创建Android.mk文件
LOCAL_SRC_FILES为c文件名,LOCAL_MODULE为so文件,应该与moduleName一致
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := Crypto LOCAL_SRC_FILES := Crypto.c include $(BUILD_SHARED_LIBRARY)
5、创建Application.mk文件
APP_ABI := armeabi表示只支持armeabi架构的jni,如需其他架构可在后面追加
APP_CFLAGS += -Wno-error=format-security APP_ABI := armeabi
编译so文件
在Terminal进入main目录下,执行ndk-build
在main/libs中会生成.so文件
在main目录下新建一个jniLibs文件夹,将libs下面的文件复制到jniLibs中,编译运行即可。
运行结果
源代码
http://download.csdn.net/download/baidu_34045013/10192722https://github.com/Caesar233/Android-NDK-Crypto
相关文章推荐
- Android JNI 调用C语言(包括解决中文乱码)
- android串口开发入门之搭建ndk开发环境及第一个jni调用程序
- Android绕过JNi 调用C语言的方法
- JNI学习2:android 调用C语言方法与C语言调用android方法
- [置顶] android利用jni调用第三方库——第二篇——编写库android程序直接调用第三方库libhello.so
- jni使用c语言调用android shell命令方法
- 编写android程序调用jni本地方法的实现
- Android Studio NDK-JNI调用C/C++程序简要步骤步骤
- android利用jni调用第三方库——第三篇——编写库android程序整合第三方库libhello.so到自己的库libhelloword.so
- Android于JNI调用列出的程序
- Android调用C++OpenCV程序的方法(NDK+JNI)
- Android使用NDK调用C语言写的SO进行加密
- Android For JNI(一)——JNI的概念以及C语言开发工具dev-c++,编写你的第一个C语言程序,使用C启动JAVA程序
- Android JNI开发之c语言调用java方法
- [置顶] android利用jni调用第三方库——第三篇——编写库android程序整合第三方库libhello.so到自己的库libhelloword.so
- android开发教程(十三)——JAVA基础之理解JNI原理(java调用C语言接口)
- Android-JNI(5)-C语言调用Java函数
- android j使用JNI实现ava语言调用C语言
- Win7下使用eclipse开发Android调用JNI-第一个程序
- Android——C语言、JNI与低层调用