最近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代码和其他语言写的代码...
Android NDK jni 常用的API Android NDK 开发时需要的常用的 JNI API 可以分为以下几类: 获取版本信息 * `jint GetVersion(JNIEnv *env);`:获取 JNI 函数版本信息,返回值为 jint 类型,在 C/C++ 中 jint 为 32...
本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....
在本文中,我们将深入探讨如何在Free Pascal (Lazarus)环境下使用Android Native Development Kit (NDK) 进行Java Native Interface (JNI)调用。这个范例将展示字符、数值、字符数组以及数值数组在Free Pascal和...
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++代码中实现...