java调用jni接口,Java 中通过jni接口调用native code
[ Java语言本身是通过Java的虚拟机解释执行的,因此对于Java中调用本地动态链接库的问题便提上了日程,为何会存在这样的需求呢?因为Java本身的机制导致一些要求高效率
在上上篇中已经介绍了如何编译native code 生成 so动态库,这里再介绍下Java中如何通过JNI接口来调用动态库中的native code方法。
通过此篇文章,我们可以认识和了解如何完整地在Android的java code中调用native code。
1 创建一个 android project, 名字叫Why
2 在工程Why中添加一个Java类,class名为Jni。这个类是一个JNI接口的Java类,文件名为Jni.java。
package com.yarin.android.Why;
public class Jni {
public native int getCInt();
public native String getCString();
}
3 将工程Why下的 "src\com\yarin\android\Why" 目录下的Jni.java文件copy到“Why\bin\classes”下.
4 Generate Jni.class file via the command below:
javac jni.java
Then copy the Jni.class file generated to cover and replace the original Jni.class file in directory “Why\bin\classes\com\yarin\android\Why”.
------The original Jni.class file, you must build the java project first to generate it.
5 Generate c style header file
javah –classpath C:\android-ndk-r6b\myproject\Why\bin\classes com.yarin.android.Why.Jni
com.yarin.android.Why is my package name appeared in Jni.java file.
com_yarin_android_Why_Jni.h is like below:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_yarin_android_Why_Jni */
#ifndef _Included_com_yarin_android_Why_Jni
#define _Included_com_yarin_android_Why_Jni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_yarin_android_Why_Jni
* Method: getCInt
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_yarin_android_Why_Jni_getCInt
(JNIEnv *env, jobject object); ---you need to supplement the parameter name yourself
/*
* Class: com_yarin_android_Why_Jni
* Method: getCString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_yarin_android_Why_Jni_getCString
(JNIEnv *env, jobject object);
#ifdef __cplusplus
}
#endif
#endif
6 Add com_yarin_android_Why_Jni.c file corresponding to the above c style header file, then add implemented code.
#include
#include
#include "com_yarin_android_Why_Jni.h"
int add()
{
int x,y;
x = 111;
y = 22;
x += y;
return x;
}
JNIEXPORT jint JNICALL Java_com_yarin_android_Why_Jni_getCInt
(JNIEnv *env, jobject object)
{
return add();
}
JNIEXPORT jstring JNICALL Java_com_yarin_android_Why_Jni_getCString
(JNIEnv *env, jobject object)
{
(*env)->NewStringUTF(env, " Why is ok ^_^ ----->> ");
}
7 然后实现在工程Why下创建目录jni,并且copy com_yarin_android_Why_Jni.c /h 到jni目录下。
8 在"Why\jni"目录下编写Android.mk ,在"android-ndk-r6b\jni"下编写Application.mk , 然后在NDK环境下编译native code,生成动态库libWhy.so。这个你已经从上上篇中知道的……。
9 在java工程中加入调用native 动态库的代码:[在Android项目中 编写c++动态链接库, 通过jni调用]
package com.yarin.android.Why;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class WhyActivity extends Activity {
static
{
System.loadLibrary("Why");
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Jni jni = new Jni();
TextView view = new TextView(this);
view.setText(jni.getCString() + Integer.toString(jni.getCInt()));
setContentView(view);
}
}
10 编译Why工程,然后 run as Android Application, 你就能看到native code的调用结果了。
Tip:
Usage of the command javah.
javah -d -classpath
where:
'outputdir' is the directory where to put the generated header file
'classpath' contains an absolute path to the directory containing your root package (as mentionned by Glen)
'fully_qualified_class' is the name of the class containing native methods without .class extension
-jni option is not required (set by default)
[1. JNIEnv对象 对于本地函数 JNIEXPORT void JNICALL Java_video1_TestNative_sayHello(JNIEnv * env, jobject obj) { cout } JNIEnv类型代表Ja
java调用jni接口,Java 中通过jni接口调用native code相关推荐
- java的标记接口_Java中的标记接口?
我被教授,Java中的Marker接口是一个空接口,用于向编译器或JVM发送信号,实现此接口的类的对象必须以特殊方式处理,如序列化,克隆等. 但最近我了解到,它实际上与编译器或JVM无关.例如,在Se ...
- java 抽象接口_JAVA中的“抽象接口”
在程序设计过程中,读者很可能遇到这样一种困境:设计了一个接口,但实现这个接口的子类并不需要实现接口中的全部方法,也就是说,接口中的方法过多,对于某些子类是多余的,我们不得不浪费的写上一个空的实现. 今 ...
- python 编程接口_Python 中的面向接口编程
前言 "面向接口编程"写 Java 的朋友耳朵已经可以听出干茧了吧,当然这个思想在 Java 中非常重要,甚至几乎所有的编程语言都需要,毕竟程序具有良好的扩展性.维护性谁都不能拒绝 ...
- java sortmap分析_Java编程中的SortedMap接口
SortedMap接口扩展了Map.它确保条目以升序排列. 当调用映射中没有任何项时,有几种方法会引发NoSuchElementException.当对象与映射中的元素不兼容时,抛出ClassCast ...
- java window.onload_从HTML中的window.onload调用webpacked代码
我在index.js中有一个导出的模块,带有一个函数start(),我希望在我的HTML的body标签中调用 以下是来自项目的代码:https://github.com/zv/tree require ...
- 为什么Java在后来的版本中,给接口增加了默认方法、静态方法、私有方法?
在业务发展过程中,发现某个功能是所有子类都需要的,那么我们该怎么办?给接口增加抽象方法吗?如果直接在接口增加抽象方法,那么所有已经写好的具体实现类就会报编译错误.因为具体类必须实现接口的全部抽象方法. ...
- java main方法调用非静态方法_java中main函数怎么调用外部非static方法
展开全部 方法可以分为静态方法和实例方法 在main函数里调用非static方法(实例方法),那么32313133353236313431303231363533e78988e69d833133336 ...
- 帝国cms纯php调用,帝国CMS模板中:使用php调用最新文章的代码(非灵动和万能标签)...
在帝国CMS模板制作中经常遇到想灵活实现效果的地方,比如跨表,结合判断等复杂调用.使用万能标签和灵动标签不足以满足要求的情况下就只能使用PHP的方法来实现!具体代码如下: $w_query=" ...
- android实现runnable接口,Android中实现Runnable接口简单例子
本课讲的是如何实现一个Runnable,在一个独立线程上运行Runnable.run()方法.Runnable对象执行特别操作有时叫作任务. Thread和Runnable都是基础的类,靠他们自己,能 ...
- mysql python 接口_Python中的MySQL接口:PyMySQL MySQLdb
MySQLdb模块只支持MySQL-3.23到5.5之间的版本,只支持Python-2.4到2.7之间的版本 PyMySQL支持 Python3.0以后的版本 PyMySQL https://pypi ...
最新文章
- c盘扩展卷是灰色的_银行电脑win7-C盘满了怎么办
- php5.6.11编译安装报错configure: error: Don't know how to define struct flock on this system
- SAP MM Purchasing Report中Selection Parameter WE101 WE103
- shell脚本知识点汇总
- MySQL的timestamp类型存储时间范围为什么是2038年之内
- PHP文件函数 记录日志功能
- flowable实战(十三):为了启动流程实例时给流程加一个标题
- go 查看全局安装了哪些包_如何用 GVM 管理 Go 项目
- day02:关于惯性导航工具箱的学习与使用:use of the progen
- MySQL数据库的常用命令语句记录——安全用户语句及函数
- 3.业务架构·应用架构·数据架构实战 --- 战略驱动的业务架构设计
- 【应用赏析】Las Vegas利用ParkPad(基于ArcPad)实现公园资产管理
- 按键精灵定时后台点击
- 计算所汉语词性标记集
- 单片机课程设计题目及要求——电风扇模拟控制系统(仿真图加代码加原理图都有)
- PMP 质量保证与质量控制的区别
- Unity 数据存储与读取_JSON
- vue中使用echarts自定义主题
- 一着不慎被蛇咬,最近半月终出坑
- ANSYS 有限元分析 后处理 General Postproc
热门文章
- 两雄争霸:解读MSU2019年度视频编码大赛
- 速抢中秋月饼和红包封面!
- 使用 pyenv 管理 Python 版本
- STL:transform
- kubernetes1.8.4 安装指南 (基于静态Pod方式安装)
- mysql打开sql语句日志
- linux 命令 nohup 后台运行
- 大剑无锋之HTTP连接、Tcp三次握手四次挥手、Tcp状态
- leetcode 39. Combination Sum | 39. 组合总和(Java)
- 面试必会系列 - 5.2 详解OSI模型与七层协议,网络TCP/IP基础,三次握手、四次挥手等