Android之JNI使用

来源:互联网 发布:linux的svn上传文件 编辑:程序博客网 时间:2024/05/17 02:03
  JNI乃Java Native Interface简称,为Java世界和Native世界之间的桥梁。自java 1.1开始JNI标准成为java平台的一部分。它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。使用java与本地已编译的代码交互,通常会丧失平台可移植性。但是,有些情况下这样做是可以接受的,甚至是必须的,比如,使用一些旧的库,与硬件、操作系统进行交互,或者为了提高程序的性能。JNI标准至少保证本地代码能工作在任何Java 虚拟机实现下。
下面通过实现简单的加法函数,来手动实现如何使用JNI。
生成JNI头文件的方法:
E:\android_proj\JNITestOne\src>javah -d ..\jni 包名.类名
生成so,还得要有NDK
Eclipse集成NDK
先下载cygwin、NDK、及CDT插件


一、下载安装cygwin
NDK运行需要借助于该工具,模拟linux的环境。
1.下载地址: http://www.cygwin.com  下载setup.exe,然后点击运行
2.安装方式选择 Install from Internet->...->选择路径的时候目录不要带有空格的->..->连接方式选择Didrect Connection
-->cygwin包下载地址 http://mirrors.kernel.org/  ,搜索列表的时候只需过滤以下包即可
autoconf2.1、automake1.14、binutils、gcc-core、gcc-g++、gdb、pcre、pcre-devel、gawk、make
下载完后测试确认:
3.运行cygwin,命令行输入 cygcheck -c cygwin 会打印出版本和状态
4.依次运行gcc -version、g++ -version、make -version、gdb -version 测试


二、下载NDK
ndk用来编译本地文件生成库
下载路径:http://developer.android.com/tools/sdk/ndk/index.html
下载完后解压即可,但需注意不要解压在路径中带有空格的文件夹下。


完成一、二后,可打开cygwin,进入到ndk/samples/hello-jni下测试NDK是否OK
$$NDK/ndk-build
如果成功则会打印出so生成的路径。


三、下载CDT插件
主要是用来在eclipse上开发C/C++代码方便一点。
下载路径:http://www.eclipse.org/cdt/downloads.php
解压后,将解压目录里的features和plugins里面新增的文件更新到eclipse目录对应的文件夹里面
然后可以创建C/C++工程。但是可能是缺少配置,有些库链不上,无法编译(未搞通??????)




四、JNI的使用
下面演示一下 Eclipse+cygwin+NDK运行android项目,演示JNI的使用过程:
1.创建Android project
创建JniTwo 类调用native方法Display(),为保证能加载libjnitwo.so,在类中定义静态方法load调用库。
package com.aug.jnidemotwo;


import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;


public class JniTwo extends Activity {


public native String Display();  //声明native方法

static {
System.loadLibrary("jnitwo");  //加载jni库
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_jni_two);
Log.d("JniTwo", Display());//调用库方法
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_jni_two, menu);
return true;
}
}


2.生成jni头文件
E:\android_proj\JNIDemoTwo>cd src


E:\android_proj\JNIDemoTwo\src>javah -d ../jni com.aug.jnidemotwo.JniTwo
注释:  -d 是将生成的.h放到指定的jni目录


E:\android_proj\JNIDemoTwo\src>ls ../jni
Android.mk  com_aug_jnidemotwo_JniTwo.cpp  com_aug_jnidemotwo_JniTwo.h
E:\android_proj\JNIDemoTwo\src>
com_aug_jnidemotwo_JniTwo.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_aug_jnidemotwo_JniTwo */


#ifndef _Included_com_aug_jnidemotwo_JniTwo
#define _Included_com_aug_jnidemotwo_JniTwo
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_aug_jnidemotwo_JniTwo
 * Method:    Display
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_aug_jnidemotwo_JniTwo_Display
  (JNIEnv *, jobject);


#ifdef __cplusplus
}
#endif
#endif




3.然后增加cpp文件实现native方法
com_aug_jnidemotwo_JniTwo.cpp
#include "com_aug_jnidemotwo_JniTwo.h"
#include <stdio.h>  
#include <jni.h> 
JNIEXPORT jstring JNICALL Java_com_aug_jnidemotwo_JniTwo_Display(JNIEnv * env, jobject jobj)
{
//env->ReleaseStringUTFChars(sRet, "abcdefg");
char *retStr = "hello, this is test!";
jstring retJstr = env->NewStringUTF(retStr);
//env->ReleaseStringUTFChars(s, str);
//printf("1111111111111");
return retJstr;
}


4.创建Android.mk编译生成so库
Android.mk


LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)


LOCAL_MODULE := jnitwo
LOCAL_SRC_FILES := com_aug_jnidemotwo_JniTwo.cpp


include $(BUILD_SHARED_LIBRARY)


5.NDK编译生成so库

运行cygwin



进入到项目目录下,执行ndk-build



android工程目录结构如下



6.运行JNIDemoTwo程序




至此,一个最简单的jni使用过程已经完成。

0 0
原创粉丝点击