仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 453|回复: 13
打印 上一主题 下一主题

[学习教程] JAVA编程:Mac及Android情况下的JNI进修仓酷云

[复制链接]
飘灵儿 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-18 11:17:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
最初被命名为Oak,目标设定在家用电器等小型系统的编程语言,来解决诸如电视机、电话、闹钟、烤面包机等家用电器的控制和通讯问题。JNI就是JavaNativeInterface,也能够了解为一样平常剧本言语的CAPI,一样平常情形下这类API的进修都是一种疾苦的精神,历来云云,没有太多手艺含量,就是一堆流畅难以了解的编程模子,编程接口,充溢着各类从以后言语到C言语的范例转换.基础的寄义就是用C言语的头脑往暗示以后的言语,这个成绩在Lua言语中抵达了极致.不论是何等为了效力,一个纯仓库操纵的编程接口都像汇编言语一样难以利用.
由于比来又入手下手做Android游戏了,用的是cocos2d-x,JNI是难以免了,之前的利用都是照猫画虎似的写几个函数挪用接口,总感到有成绩,明天好好的进修进修吧.
与一样平常关于JNI文章略微有些纷歧样的是,本文会更多的存眷于Android相干的成绩.
本文利用的情况是:

MacOSX10.8.3

javaversion"1.6.0_43"

Java(TM)SERuntimeEnvironment(build1.6.0_43-b01-447-11M4203)

JavaHotSpot(TM)64-BitServerVM(build20.14-b01-447,mixedmode)

gccversion4.2.1(BasedonAppleInc.build5658)(LLVMbuild2336.11.00)

AndroidSDKAPI17
Androidndkr8d
从Java中挪用C/C++库

从Java中挪用C/C++库的典范利用场景就是在Android中Load本人写的游戏库,然后运转.固然有cocos2d-x引擎的时分你几近不必体贴这个.
HelloWorld

从R&D入手下手,HelloWorld就成了一入手下手必用的例子了,进修JNI也从这个入手下手吧.

起首构建一个最复杂的Javaclass:
  1. //HelloWorld.javaimportjava.lang.System.*;publicclassHelloWorld{publicnativevoidSayHelloWorld();publicstaticvoidmain(String[]args){System.loadLibrary("helloworld");HelloWorldhelloworld=newHelloWorld();helloworld.SayHelloWorld();}}
复制代码
native关头字暗示的接口就是必要用C/C++来完成的接口,System.loadLibrary挪用的就是将会完成的jni库.

然后用javac将文件编译成字节码:
  1. javacHelloWorld.java
复制代码
天生HelloWorld.class,java中最人道的一点就是把binding的天生间接作为尺度了,这一点比Python和lua要强多了,也使得JNI的利用是我打仗过的言语中,相似CAPI最便利的一个.间接天生C/C++binding头文件的体例是用javah命令:
  1. javahHelloWorld
复制代码
从下面的HelloWorld类天生的头文件以下:
  1. /*DONOTEDITTHISFILE-itismachinegenerated*/#include<jni.h>/*HeaderforclassHelloWorld*/#ifndef_Included_HelloWorld#define_Included_HelloWorld#ifdef__cplusplusextern"C"{#endif/**Class:HelloWorld*Method:SayHelloWorld*Signature:()V*/JNIEXPORTvoidJNICALLJava_HelloWorld_SayHelloWorld(JNIEnv*,jobject);#ifdef__cplusplus}#endif#endif
复制代码
这其实是相称人道化了,我们只必要包括HelloWorld.h头文件,然后完成依照头文件给的署名完成Java_HelloWorld_SayHelloWorld函数就好了,而不必本人往记着这么庞大的函数名和参数.完成的HelloWorld.cc文件以下:
  1. //HelloWorld.cc#include"HelloWorld.h"#include<cstdio>JNIEXPORTvoidJNICALLJava_HelloWorld_SayHelloWorld(JNIEnv*,jobject){printf("HelloWorld.n");}
复制代码
编译C++代码的时分在MacOS下和在Linux,Windows有所分歧,不是编译成.so大概dll,而是MacOS本人的jnilib.而且jni.h的目次也对照特别,是/System/Library/Frameworks/JavaVM.framework/Headers/,这个必要略微注重一下,详细的命令以下:
  1. g++-dynamiclib-olibhelloworld.jnilibHelloWorld.cc-frameworkJavaVM-I/System/Library/Frameworks/JavaVM.framework/Headers
复制代码
此时统统停当:
  1. >javaHelloWorldHelloWorld.
复制代码
带参数的函数

两个言语之间的往返挪用,在没有任何参数的情形下还好,有了参数今后,由于扳连到两个言语对范例的分歧暗示体例,必要举行范例转换,是最贫苦的中央,好比在Lua,Python中,利用CAPI时,你就必要记着Lua和Python的各类范例分离对应C言语中的哪一个范例,JAVA中在挪用C/C++函数时,在Java中经由过程javah部分减缓了这个成绩,可让我们间接晓得对应的范例是哪个,不外详细每一个用C言语暗示的JAVA范例该怎样用,仍是查文档吧,好比上面这个例子:
  1. //ArugmentTest.javaimportjava.lang.System.*;publicclassArgumentTest{publicnativeintintMethod(intn);publicnativebooleanbooleanMethod(booleanbool);publicnativeStringstringMethod(Stringtext);publicnativeintintArrayMethod(int[]intArray);publicstaticvoidmain(String[]args){System.loadLibrary("argumenttest");ArgumentTestobj=newArgumentTest();System.out.println("intMethod:"+obj.intMethod(5));System.out.println("booleanMethod:"+obj.booleanMethod(true));System.out.println("stringMethod:"+obj.stringMethod("JAVA"));System.out.println("intArrayMethod:"+obj.intArrayMethod(newint[]{1,2,3,4,5}));}}
复制代码
编译后,用javah天生的头文件以下:
  1. /*DONOTEDITTHISFILE-itismachinegenerated*/#include<jni.h>/*HeaderforclassArgumentTest*/#ifndef_Included_ArgumentTest#define_Included_ArgumentTest#ifdef__cplusplusextern"C"{#endif/**Class:ArgumentTest*Method:intMethod*Signature:(I)I*/JNIEXPORTjintJNICALLJava_ArgumentTest_intMethod(JNIEnv*,jobject,jint);/**Class:ArgumentTest*Method:booleanMethod*Signature:(Z)Z*/JNIEXPORTjbooleanJNICALLJava_ArgumentTest_booleanMethod(JNIEnv*,jobject,jboolean);/**Class:ArgumentTest*Method:stringMethod*Signature:(Ljava/lang/String;)Ljava/lang/String;*/JNIEXPORTjstringJNICALLJava_ArgumentTest_stringMethod(JNIEnv*,jobject,jstring);/**Class:ArgumentTest*Method:intArrayMethod*Signature:([I)I*/JNIEXPORTjintJNICALLJava_ArgumentTest_intArrayMethod(JNIEnv*,jobject,jintArray);#ifdef__cplusplus}#endif#endif
复制代码
这里我们能够看到,也许的范例对应干系:
Object=>jobject

int=>jint

boolean=>jboolean

String=>jstring

int[]=>jintArray
可是,jobject,jstring,jintArray详细怎样利用,总回得再进修一遍.可是javah的存在仍是十分成心义的,最少我们不必记哪一个范例该查甚么文档了.

完成的C++文件以下:
  1. //ArgumentTest.cc#include"ArgumentTest.h"#include<cstring>usingnamespacestd;JNIEXPORTjintJNICALLJava_ArgumentTest_intMethod(JNIEnv*env,jobjectobj,jintnum){returnnum*num;}JNIEXPORTjbooleanJNICALLJava_ArgumentTest_booleanMethod(JNIEnv*env,jobjectobj,jbooleanboolean){return!boolean;}JNIEXPORTjstringJNICALLJava_ArgumentTest_stringMethod(JNIEnv*env,jobjectobj,jstringstr){constchar*cstr=env->GetStringUTFChars(str,0);charcap[128]="language:";strcat(cap,cstr);env->ReleaseStringUTFChars(str,cstr);returnenv->NewStringUTF(cap);}JNIEXPORTjintJNICALLJava_ArgumentTest_intArrayMethod(JNIEnv*env,jobjectobj,jintArrayarray){jsizelen=env->GetArrayLength(array);jint*body=env->GetIntArrayElements(array,0);intsum=0;for(inti=0;i<len;++i){sum+=body[i];}env->ReleaseIntArrayElements(array,body,0);returnsum;}
复制代码
这里能够看到几个特别的函数,GetStringUTFChars,GetArrayLength,GetIntArrayElements,ReleaseIntArrayElements等,还好都不算太庞大.一旦用了JNI,必要注重的就是,你资本的分派开释,就得和C/C++中一样了,得本人手动来.

别的,还值得一提的是,由于C++对类的间接撑持,以是C++中能够用比C言语更简便的语法,也许的区分看了上面的示例:

C代码:(*env)->GetStringUTFChars(env,string,0);
C++代码:env->GetStringUTFChars(string,0);
Android中的情形

实在完成和利用体例都相似,只是编译时,必要利用分歧的命令,实在由于Android实在就是一种特别的Linux,以是关于Android来讲,天生体例和Linux相似,而且都是天生Unix/Linux通用的.so静态库文件.

别的,另有一些典范的Android的成绩,好比在Android中往完成后面的ArugmentTest:
  1. javacHelloWorld.java0
复制代码
必要注重的是,Android中就不要利用System.out这类尺度JAVA的库输入了,用的是android.util.Log这个再LogCat输入的类.然后,作为Android的工程,一个Activity是必需的,这里就把ArgumentTest做成了Activity了.

编译的时分必要注重,一方面在Android中,我们一定必要指定一个本人的package,不克不及像后面何处随便了,这里的pakcage我用的是com.jtianling.ArgumentTest,别的,还必要指定一下android的classpath:
  1. javacHelloWorld.java1
复制代码
一样的,pacakge在用javah的时分也必不成少,否则就算天生了.so,实在package对不上也是找不到的.起首进进jni目次,然后用上面的命令,指定好package.
  1. javacHelloWorld.java2
复制代码
此时天生的头文件是带package信息的,也许是上面如许子:

com_jtianling_ArgumentTest_ArgumentTest.h
文件的函数名也是相似,也附带了package的信息:
  1. javacHelloWorld.java3
复制代码
一样的,依照署名和函数名完成便可,在一个典范的Android工程中,jni相干的C/C++代码都是放在工程的jni目次下,我们还需在此目次设置Android.mk文件,也许以下:
  1. javacHelloWorld.java4
复制代码
我们利用ndk-build来编译android的jni静态库.编译的输出以下:

java比较简单,没有C++的烦琐,但学习时最好有C++为基础.与JSP和SQL起应用,功能强大.
老尸 该用户已被删除
沙发
发表于 2015-1-24 11:19:39 | 只看该作者
接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。
若相依 该用户已被删除
板凳
发表于 2015-1-25 19:03:30 | 只看该作者
象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。
简单生活 该用户已被删除
地板
发表于 2015-2-3 13:57:33 | 只看该作者
是一种使网页(Web Page)产生生动活泼画面的语言
愤怒的大鸟 该用户已被删除
5#
发表于 2015-2-4 13:15:48 | 只看该作者
你一定会高兴地说,哈哈,原来成为Java高手就这么简单啊!记得Tomjava也曾碰到过一个项目经理,号称Java很简单,只要三个月就可以学会。
精灵巫婆 该用户已被删除
6#
发表于 2015-2-6 07:58:07 | 只看该作者
接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。
只想知道 该用户已被删除
7#
发表于 2015-2-7 12:55:17 | 只看该作者
J2SE开发桌面应用软件比起 VC,VB,DEPHI这些传统开发语言来说,优势好象并不明显。J2ME对于初学者来说,好象又有点深奥,而且一般开发者很难有开发环境。
分手快乐 该用户已被删除
8#
发表于 2015-2-8 14:56:26 | 只看该作者
Pet Store.(宠物店)是SUN公司为了演示其J2EE编程规范而推出的开放源码的程序,应该很具有权威性,想学J2EE和EJB的朋友不要 错过了。
兰色精灵 该用户已被删除
9#
发表于 2015-2-22 04:25:18 | 只看该作者
是一种语言,用以产生「小应用程序(Applet(s))
乐观 该用户已被删除
10#
发表于 2015-3-5 01:25:48 | 只看该作者
Pet Store.(宠物店)是SUN公司为了演示其J2EE编程规范而推出的开放源码的程序,应该很具有权威性,想学J2EE和EJB的朋友不要 错过了。
再见西城 该用户已被删除
11#
发表于 2015-3-11 22:07:17 | 只看该作者
是一种语言,用以产生「小应用程序(Applet(s))
金色的骷髅 该用户已被删除
12#
发表于 2015-3-11 22:25:48 | 只看该作者
一般学编程语言都是从C语开始学的,我也不例外,但还是可能不学过程语言而直接学面向对象语言的,你是刚接触语言,还是从C开始学比较好,基础会很深点,如果你直接学习JAVA也能上手,一般大家在学语言的时候都记一些语言的关键词,常有的包和接口等。再去做逻辑代码的编写,以后的学习过程都是从逻辑代码编写中提升的,所以这方面都是经验积累的。你要开始学习就从
冷月葬花魂 该用户已被删除
13#
发表于 2015-3-19 15:08:12 | 只看该作者
你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。
第二个灵魂 该用户已被删除
14#
发表于 2015-3-28 13:30:43 | 只看该作者
Jive的资料在很多网站上都有,大家可以找来研究一下。相信你读完代码后,会有脱胎换骨的感觉。遗憾的是Jive从2.5以后就不再无条件的开放源代码,同时有licence限制。不过幸好还有中国一流的Java程序员关注它,外国人不开源了,中国人就不能开源吗?这里向大家推荐一个汉化的Jive版本—J道。Jive(J道版)是由中国Java界大名 鼎鼎的banq在Jive 2.1版本基础上改编而成, 全中文,增加了一些实用功能,如贴图,用户头像和用户资料查询等,而且有一个开发团队在不断升级。你可以访问banq的网站
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-11-15 18:44

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表