最近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实现AES** 1. **创建JNI接口**:首先,你需要在Java层定义JNI接口,这些接口将被C++代码实现。例如: ```java static { System.loadLibrary("aes"); } public native byte[] ...
在Android开发中,JNI通常与NDK一起使用,以便将计算密集型的任务移到C++中,利用其高效的运算能力。下面我们将深入探讨Android NDK与JNI的应用及实现过程。 **JNI基础知识** 1. **JNI头文件**:编写JNI代码前,...
在Android开发中,NDK(Native Development Kit)和JNI(Java Native Interface)是两个关键工具,它们允许开发者在Android应用中使用C/C++代码。这个"Android NDK+JNI 练习1"很可能是为了帮助开发者熟悉如何在本地C...
Android NDK-JNI开发是Android应用开发中的一个重要领域,它涉及到原生代码的集成和调用,以利用C++或其它本地语言的高效性能。JNI(Java Native Interface)是Java平台的一部分,允许Java代码和其他语言写的代码...
本Demo代码主要展示了如何在Android Studio中配置NDK和JNI,以便在Android应用中使用本地库。 首先,我们需要了解NDK的基本概念。NDK是一套工具集,允许开发者在Android应用中使用C和C++代码,这可以提高性能,尤其...
在Android开发中,NDK(Native Development Kit)和JNI(Java Native Interface)是两个关键工具,它们允许开发者在原生代码(如C/C++)和Java代码之间进行交互。本练习2主要关注如何在Android NDK和JNI的帮助下,从...
这是Android NDK开发标准的JNI和Android.mk编写模版,里面的一些东西可能涉及我的项目,但不影响观看
在Android应用开发中,NDK和JNI结合使用,通常用于实现计算密集型任务、游戏引擎、音视频处理等场景。 要开始一个简单的Android NDK和JNI项目,我们首先会创建一个"Hello JNI"示例。这个例子将展示如何在Android...
附件是Android下检测ndk和jni内存泄漏的demo,可以用于native中malloc和free的检测。使用方法(参见博客):https://blog.csdn.net/zhuyong006/article/details/88537499
本篇我们将深入探讨如何使用Android NDK和JNI来生成本地动态链接库(so库)。 首先,我们需要了解NDK的基本工作流程。当你在Java代码中声明一个本地方法(如`native void someNativeFunction();`),Android Studio会...
《Android NDK与JNI实战:史上最详尽的NDK入门指南》 在移动开发领域,Android NDK(Native Development Kit)和JNI(Java Native Interface)是开发者用来实现高性能计算、利用硬件加速或调用C/C++库的重要工具。...
在Android开发中,NDK(Native Development Kit)和JNI(Java Native Interface)是两个关键工具,它们允许开发者在Android应用中使用C/C++代码。这个"Android NDK+JNI 练习3"的主题聚焦于如何从C++对象调用Java层的...
在Android开发中,NDK(Native Development Kit)和JNI(Java Native Interface)是两个关键工具,它们允许开发者在Android应用中使用C/C++代码。本文将深入探讨如何在Android Studio中利用NDK和JNI,以及它们的应用...
在Android应用开发中,NDK(Native Development Kit)和JNI(Java Native Interface)是两个重要的技术,用于实现Java代码与本地C/C++代码的交互。本实战教程将深入探讨NDK-JNI的开发过程,结合具体的AES加密DEMO,...
在Android中,使用NDK和JNI实现CRC16编码的过程如下: 1. **创建JNI接口**: 在Java层定义一个JNI方法,声明为`native`关键字,用于调用C++代码。例如: ```java public class Crc16Util { static { System....
Android NDK 自动生成jni头文件 Android NDK 中生成 jni 头文件是 JNI 开发中的一個重要步驟。JNI(Java Native Interface)是一個允許 Java 代码调用 Native 代码的接口,通過 JNI,可以將 Java 代码與 Native ...
"HelloNDK"是一个经典的入门示例,它展示了如何在Android应用中使用NDK和JNI。该示例通常包括以下几个关键部分: 1. Java源代码:在Java层创建一个类,声明本地方法(native method),这些方法将在C/C++代码中实现...
Android NDK和JNI是Android应用开发中的重要工具,它们允许开发者使用C++或者其他原生语言编写部分代码,以实现性能优化、利用硬件加速或者集成已有的C/C++库。本示例代码“android-ndk-jni”是针对这一主题的具体...