您的位置:首页 > 编程语言 > Java开发

如何编写和调用java的jni程序

2017-03-14 11:13 417 查看
http://www.cnblogs.com/gansc23/archive/2011/03/27/1996790.html

项目进行接近一个月,很多功能和实现都日渐清晰,为了保证项目进度,客户端对服务器(j2ee)请求的验证模块的开发势在必行。

由于涉及到安全性和代码通用性,决定用C语言来实现验证模块,同时部署到客户端和服务器,经过半天的研究终于成功进行jni调用,现将步骤附上:

1.新建一个java工程,目录是D:\project\MyProject,以下用<project>代替。

2.新建一个jni类:com.mycompany.jni.MyAuthToken,并书写java的native接口方法和其它代码。如下:

package com.mycompany.jni;

/**
* @author gansc23
*/
public class MyAuthToken
{
/**
* 生成鉴权token
*
* @param imei 设备的IMEI号
* @param imsi sim卡的IMESI号
* @param utc 格林威治时间
* @param agent 设备代理。如 "moto mb525"
* @param random 随机数
* @return
*/
public static native String getToken(
String imei,
String imsi,
String agent,
long timestamp,
int random );
}

3. 命令行进入<project>\src\com\mycompany\jni  目录,运行命令 javac
MyAuthToken.java,将生成的 MyAuthToken.class 文件剪切到 <project>\bin\com\mycompany\jni 目录下,覆盖之前的文件。

4.命令行进入<project>\bin 目录,运行命令 javah
-jni com.mycompany.jni.MyAuthToken,将生成的 <project>\bin\com_mycompany_jni_MyAuthToken.h 文件拷贝到 <project>\jni\目录。

5. 在<project>\jni\ 目录中实现方法和其它的c/c++文件。假设实现文件的清单如下:
com_mycompany_MyAuthToken.h (自动生成的,不用修改)
com_mycompany_MyAuthToken.c
aaa.h
aaa.c
bbb.h
bbb.c

6. 将c文件编译并打包成库。
笔者这里在Windows 7上安装了Cygwin交叉编译环境,在java环境和android环境上的指令有少许不同:

6.1 在jdk环境下:

6.1.1 启动Cygwin,进入/cygdrive/d/project/MyProject/jni 目录( 即 <project>\jni\ 目录 ),运行以下命令编译生成*.o文件:

gcc -c com_mycompany_MyAuthToken.c aaa.c bbb.c

6.1.2 编译成功之后,在 <project>\jni 目录下会生成 com_mycompany_MyAuthToken.o,aaa.o和bbb.o文件。
再运行以下命令将 *.o 文件链接成库文件:

gcc-3 -mno-cygwin -shared -o myauthtoken.dll com_mycompany_MyAuthToken.o aaa.o bbb.o

6.1.3 将生成的myauthtoken.dll放到 C:\Windows\System32\ 目录下 (正式开发中应该放到工程目录中进行调用)。

6.1.4 新建一个测试类 com.mycompany.MyAuthTokenTester
代码如下:

package com.mycompany;

import com.mycompany.jni.MyAuthToken;

public class MyAuthTokenTester {

static {
System.loadLibrary("myauthtoken"); // 不要带后缀名!!
}

/**
* @param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
System.out.printf(
MyAuthToken.getToken("imei", "imsi", "agent", 23453252L, 3252) );
}
}

运行 MyAuthTokenTester.main(),OK,大功告成!

6.2 在Android开发环境下

6.2.1 首先下载和解压Android NDK,笔者这里下载的是 android-ndk-r5,解压目录是 D:\android-ndk\android-ndk-r5。

6.2.2 为了方便开发,进入cygwin的安装目录,编辑 <cygwin_install>/home/Administrator/.bash_profile文件,在文件末尾添加如下命令:

ANDROID_NDK_ROOT=/cygdrive/d/android-ndk/android-ndk-r5
export ANDROID_NDK_ROOT

ndk=/cygdrive/d/android-ndk/android-ndk-r5
export ndk

6.2.3 在项目的 <project>\jni 目录中新建一个名为 Android.mk的make文件,编写内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := authtokenmodule
LOCAL_SRC_FILES := aaa.c bbb.c \
  com_mycompany_MyAuthToken.c

#LOCAL_PRELINK_MODULE := false

# for logging
LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)

6.2.4 在项目的 <project>\ 根目录下新建一个名为 Application.mk的make文件,编写内容如下:

# The ARMv7 is significanly faster due to the use of the hardware FPU

# Build both ARMv5TE and ARMv7-A machine code.
#APP_ABI := armeabi armeabi-v7a

#APP_PLATFORM := android-9

APP_PROJECT_PATH := $(call my-dir)

APP_MODULES := authtokenmodule

6.2.5 启动Cygwin,进入/cygdrive/d/project/MyProject/jni 目录( 即 <project>\jni\ 目录 ),运行以下命令:

$ndk/ndk-build

编译成功后,会在 <project>/libs/armeabi 目录下生成 libauthtokenmodule.so 库文件。

6.2.6 部署jni库

1)若是部署到真机上则直接将打包好的apk文件安装上就ok。 :)

2)若在开发阶段部署到模拟器上则要稍微繁琐一点:
在命令行中运行以下命令:

emulator -avd {your_avd_name} -partition-size 128
adb -s {your_avd_serial} remount

命令行进入 <project>/libs/armeabi 目录,运行以下命令:

adb -s {your_avd_serial} push libauthtokenmodule.so /system/lib

最后不要忘记将so库载入到程序进程中  :)

public class SplashActivity {

static {
System.loadLibrary("authtokenmodule"); // 不要带后缀名!!
}

...
}

分类: Basic
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: