[Android] Linux下JNI简单实现过程
大概梳理了一下JNI的过程:
start->先写好A.java文件,里面添加native方法B,调用库C.so->编译成.class文件->用javac生成.h文件,文件包含Java_A_B的方法声明->在.c文件实现方法->.c编为C.so库文件->运行A.java->end
下面是具体步骤。
本文地址:http://www.cnblogs.com/rossoneri/p/4359840.html
首先编写一个java程序
HelloJNI.java
public class HelloJNI{
public native void displayHelloJNI();//所有native关键词修饰的都是对本地的声明 static{
System.loadLibrary("MyLib");//载入本地库
} public static void main(String[] args){
new HelloJNI().displayHelloJNI();
}
}
声明native方法:如果你想将一个方法做为一个本地方法的话,那么你就必须声明该方法为native的,并且不能实现。
System.loadLibrary("MyLib");加载动态库
我们可以这样理解:我们的方法 displayHelloWorld()没有实现,但是我们在下面就直接使用了,所以必须在使用之前对它进行初始化)这里一般是以static块进行加载的。同时需要注意的是System.loadLibrary();的参数“hello”是动态库的名字。
编译写好的java文件
javac HelloJNI.java 得到 HelloJNI.class
生成.h头文件
javah HelloJNI
得到 HelloJNI.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */ #ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloJNI
* Method: displayHelloJNI
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloJNI_displayHelloJNI
(JNIEnv *, jobject); #ifdef __cplusplus
}
#endif
#endif
这个h文件相当于我们在java里面的接口,这里声明了一个Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致
编写本地方法
实现和由javah命令生成的头文件里面声明的方法名相同的方法。
test.c
#include<stdio.h>
#include"jni.h"
#include"HelloJNI.h" JNIEXPORT void JNICALL Java_HelloJNI_displayHelloJNI
(JNIEnv *env, jobject obj)
{
printf("this is a JNI test program!\n");
return;
}
需要将jni.h(该文件可以在%JAVA_HOME%/include文件夹下面找到)文件引入,因为在程序中的JNIEnv、 jobject等类型都是在该头文件中定义的;另外在第2行需要将HelloWorld.h头文件引入(我是这么理解的:相当于我们在编写java程序的时候,实现一个接口的话需要声明才可以,这里就是将HelloWorld.h头文件里面声明的方法加以实现。当然不一定是这样)。
编译动态链接库
将test.c编译成动态链接库 当前目录下
gcc -shared -I /home/du/jdk1..0_71/include -I /home/du/jdk1..0_71/include/linux test.c -o libMyLib.so
得到libMyLib.so动态链接库
在HelloJNI.java中我们LoadLibrary方法加载的是“MyLib”,
可我们生成的Library却是libMyLib。这是Linux的链接规定的,
一个库的必须要是:lib+库名+.so。链接的时候只需要提供库名就可以了
运行
运行HelloJNI.java
java HelloJNI
Exception in thread "main" java.lang.UnsatisfiedLinkError: no MyLib in java.library.path
java -Djava.library.path=. HelloJNI
运行 或者
export LD_LIBRARY_PATH=/home/du/test_code:$LD_LIBRARY_PATH
java HelloJNI
即可获得输出。
参考
[Android] Linux下JNI简单实现过程的更多相关文章
- Android studio 下JNI编程实例并生成so库
Android studio 下JNI编程实例并生成so库 因为公司需要为Android相机做美颜等图像后期处理,需要使用JNI编程,最近学了下JNI,并且在Android Studio下实现了一个小 ...
- Linux下一个简单的日志系统的设计及其C代码实现
1.概述 在大型软件系统中,为了监测软件运行状况及排查软件故障,一般都会要求软件程序在运行的过程中产生日志文件.在日志文件中存放程序流程中的一些重要信息, 包括:变量名称及其值.消息结构定义.函数返回 ...
- [oracle] oracle的三种密码验证机制以及在windows和linux下的不同启动过程
oracle数据库的密码验证机制: ① 操作系统验证 拥有SYSDBA和SYSOPER的用户用该方式验证此时数据库无需启动,也无需开启监听和实例服务. 要求:本地组ora_dba中有该操作系统的登录用 ...
- Android Studio下的简单网页解析
Android Studio下的简单网页解析 一.导入数据 导入前添加依赖 implementation 'org.jsoup:jsoup:1.11.3' 使用字符串导入 String html = ...
- Android studio 下 JNI 开发实例
在AS中进行 NDK 开发之前,我们先来简单的介绍几个大家都容易搞懵的概念: 到底什么是JNI,什么是NDK? 何为“交叉编译”? 先看什么是 JNI?JNI 的全称就是 Java Native In ...
- (转)linux下mysql的安装过程
最近在linux安装了mysql,根据网上收集的资料和个人的操作过程,大概做了个整理,以便以后进行参考回顾. 1.下载mysql-5.1.36.tar.gz,并且解压. tar -xzvf mysql ...
- Linux下main函数启动过程【程序员自我修养笔记】【自用】
1. 入口函数和程序初始化 1.1 程序从main开始吗? 当程序执行到main函数的第一行时,很多事情都已经完成了: [证1]如下是一段C语言代码: 代码中可以看到,在程序刚刚执行到main的时候, ...
- Android Studio下jni应用
最近在将一个小应用从eclipse开发迁移到android studio,程序中有native代码实现,在eclipse是靠Android.mk这么个mk文件来组织编译的,但到android stud ...
- Linux下安装mongodb详细过程
本次安装mongodb使用yum.repo方式.详细过程请参考,也列出一些安装过程中的错误,欢迎指正. mongodb版本:3.0 先在linux下cd 到 /etc/yum.repos.d/ 新建脚 ...
随机推荐
- MVC3学习:利用mvc3+ajax实现删除记录
首先根据模板生成list视图,上面就会有一个delete的链接,但是模板自带的这种删除,需要另外再打开一个删除页,再进行删除.我们可以利用ajax来改写,实现在当前页删除. 在视图上面,将原来的 @H ...
- Install nginx on centos
1. 安装wget. sudo yum -y install wget 2. 下载nginx发布代码. sudo wget http://nginx.org/download/nginx-1.8.0. ...
- charles撰写工具/compose和Compose New
撰写工具/compose和Compose New compose 是在原有的请求基础上,修改: compose New 是新出一个弹窗,自己手动一个个的去写: 可以写各种状态:– URL:– Meth ...
- mpvue小程序图片404
mpvue开发小程序时候,要添加静态本地图片 <img src="../../images/bg.png" alt=""> 会报错: VM14878 ...
- jQuery WeUI实现分页功能
使用前记得先引入:weui.min.css.jquery-weui.min.css.jquery-weui.min.js 第一步:将下面的代码放在body结束标签上面(这个位置可以自己按需求放) &l ...
- 堆与堆排序/Heap&Heap sort
最近在自学算法导论,看到堆排序这一章,来做一下笔记.堆排序是一种时间复杂度为O(lgn)的原址排序算法.它使用了一种叫做堆的数据结构.堆排序具有空间原址性,即指任何时候都需要常数个额外的元素空间存储临 ...
- Deep learning with Python 学习笔记(4)
本节讲卷积神经网络的可视化 三种方法 可视化卷积神经网络的中间输出(中间激活) 有助于理解卷积神经网络连续的层如何对输入进行变换,也有助于初步了解卷积神经网络每个过滤器的含义 可视化卷积神经网络的过滤 ...
- vue路由管理-保留滚动位置功能、按需加载模块名自定义
路由管理:保留滚动位置 其实现与组件的keep-alive相关,仅设置了keep-aive的页面,实施保留回退位置能力. keep-alive介绍 作用 把切换出去的组件保留在内存中,可以保留它的状态 ...
- Linux中locate命令的实践总结
locate 让使用者可以很快速的搜寻档案系统内是否有指定的档案.其方法是先建立一个包括系统内所有档案名称及路径的数据库,之后当寻找时就只需查询这个数据库,而不必实际深入档案系统之中了.在一般的 di ...
- 如何一键式搭建微信小程序
有了微信小程序,对你到底意味着什么? 对于用户来说,再也不用担心手机的内存不够用了!一个小程序只有1M,随便卸载一个App,就能安装很多小程序! 对于老板来说,你不再需要花费数十万来去请外包公司帮你去 ...