最近android项目中底层加密方法需要用c实现,这样调用就需要用到jni了,以下是我学习的一点心得,写出来分享一下:
1、准备工具
需要Android NDK和windows下c、c++代码的编译器cygwin
android-ndk-r9-windows.zip下载地址:http://developer.android.com/tools/sdk/ndk/index.html
cygwin下载地址:http://u.115.com/file/clvy46eb
2、环境配置
1. 解压缩NDK和cygwin,并配置cygwin的环境变量。
例如:我解压缩到D盘根目录,那么在环境变量的path中添加:”D:\cytwin\bin;”,
如下图所示。
2. 在命令行中进入cygwin目录,并执行cygwin.bat,如果你不是用Administrator账号登录的系统,那么会在cygwin\home\文件夹中生成一个以你的登录名命名的新的文件夹。
3. 修改新生成文件夹中的“.bash_profile ”文件,用UE或editplus等文本编辑器打开,在最后增加:
NDK=/cygdrive/d/android-ndk-r6
export NDK
然后保存关闭。
d/android-ndk-r6表示ndk在d盘,如果你的ndk放到了其他盘符或路径,例如放到e:\sdk目录中,那么就改为e/sdk/android-ndk-r6。
(如果是Administrator账号登录,直接修改Administrator文件夹中的文件。)
四.开始使用
1.在命令行窗口中进入cygwin目录,执行cygwin.bat
2.进入android-ndk中的samples文件夹里的某个项目文件夹,这里以hello-jni为例
进入文件夹的方式与MS-DOS类似,用cd + 空格 + 盘符+ 路径即可,例子见下图
3.执行$NDK/ndk-build编译
4.例子编译成功后得到libhello-jni.so文件,到此环境就配置好了
五、在自己的项目中使用jni
1、首先写java调用的native方法,示例代码如下:
package com.magic.point;
public class EncryptJNI {
static {
System.loadLibrary("magic-point-jni");
}
public static native void init();
public static native String getHiddenString(int index);
}
2、在jni中c的方法名名称需要是固定格式,我们可以javac EncryptJNI 编译java文件,然后用
javah -jni com.magic.point.EncryptJNI 编译生成com_magic_point_EncryptJNI.h头文件,格式如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_magic_point_EncryptJNI */
#ifndef _Included_com_magic_point_EncryptJNI
#define _Included_com_magic_point_EncryptJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_magic_point_EncryptJNI
* Method: init
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_magic_point_EncryptJNI_init
(JNIEnv *, jclass);
/*
* Class: com_magic_point_EncryptJNI
* Method: getHiddenString
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_magic_point_EncryptJNI_getHiddenString
(JNIEnv *, jclass, jint);
#ifdef __cplusplus
}
#endif
#endif
我们可以看到命名格式如下:
JNIEXPORT jstring JNICALL Java_全包名_类名_getHiddenString()
3、接下来我们就可以新建一个Hellojni.c文件,导入com_magic_point_EncryptJNI.h头文件,在c里面具体实现头文件中的方法,完成后将com_magic_point_EncryptJNI.h和Hellojni.c文件复制到android-ndk-r9/samples/hello-jin/ 的jni目录下,修改mk配置文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Hello-jin //编译生成的so文件名称
LOCAL_SRC_FILES := Hellojin.c //需编译的文件
include $(BUILD_SHARED_LIBRARY)
执行$NDK/ndk-build编译将生成libHello-jni.so文件,将libHello-jni.so文件复制到android工程libs目录下,调用String result=EncryptJNI.getHiddenString(0); 即可。
六,jni中的类型转换
在jni中的数据类型和java中可直接使用的类型不用,需要转换一下,以下列出char 转jstring类型和jstring类型转char的方法
1、char 转 jstring
const char * name;
jstring jstr = (*env)->NewStringUTF(env,name);
2、jstring 转 char
char* jstringToChar(JNIEnv* env, jstring jstr)
{
char* rtn = NULL;
jclass clsstring = (*env)->FindClass(env,"java/lang/String");
jstring strencode = (*env)->NewStringUTF(env,"utf-8");
jmethodID mid = (*env)->GetMethodID(env,clsstring, "getBytes", "(Ljava/lang/String;)[B");
jbyteArray barr= (jbyteArray)(*env)->CallObjectMethod(env,jstr, mid, strencode);
jsize alen = (*env)->GetArrayLength(env,barr);
jbyte* ba = (*env)->GetByteArrayElements(env,barr, JNI_FALSE);
if (alen > 0)
{
rtn = (char*)malloc(alen + 1);
memcpy(rtn, ba, alen);
rtn[alen] = 0;
}
(*env)->ReleaseByteArrayElements(env,barr, ba, 0);
return rtn;
}
相关推荐
android ndk举例 jni
Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例Android NDK JNI 经典实例
Android NDK 开发时需要的 常用的JNI API
这是Android NDK开发标准的JNI和Android.mk编写模版,里面的一些东西可能涉及我的项目,但不影响观看
android studio cmake android ndk-jni动态库开发,这个可以在cmake下链接生成多个so库
附件是Android下检测ndk和jni内存泄漏的demo,可以用于native中malloc和free的检测。使用方法(参见博客):https://blog.csdn.net/zhuyong006/article/details/88537499
Android 用ndk+jni编译C++文件代码,实现crc16加密数据,给Android调用
Android-ndk-jni AES加解密 压缩文件里面有 aes加解密 .c .h 文件 还用使用方法
Native C函数调用Java函数,如何活用JNI和 NDK 来让 Native C函数顺利呼叫Java函数
Ndk-Jni demo
一个经过在Eclips模拟器上运行的NDK-JNI案例。
Android Studio中使用NDK/JNI 的相关代码http://blog.csdn.net/jfzl123/article/details/53436600
ndk demo开发过程在http://blog.csdn.net/gzjck/article/details/51724970
Android的NDK与JNI雕龙小技.pdf
android NDK 自动生成jni头文件 要所java 类自动生成jni调用头文件。
由更底层的C++ Object來调用Java层的函数:如何让底层的C++ Object能调用Java层的函数
在Native C函数中创建Java Object:如何由C 模块來创建Java Object
android_ndk_jni_dev.zip 配套例子
JNI中文文档详细介绍里边带示范案例 NDK中文文档详细介绍了如何搭建Android开发环境以及如何编写ndk的makefile编译脚本,如何使用jni+ndk在Android上开发c++程序 不多说,学习开发Android程序的好东西
原文链接 http://blog.csdn.net/u012840567/article/details/53283274