android jni——helloworld
看了网上好多牛人写的学习系列都是用HelloWorld作为开始,我们这里也用HelloWorld来开始我们的学习,首先我们来介绍下JNI吧。
JNI作为java代码和C/C++的桥梁而存在的,为了让java代码更加接近原生代码,大家都知道在linux中,C语言可以直接访问硬件,但是java代码想要直接操作硬件或者说是直接读写寄存器的话不行,所以需要jni来作为桥梁来访问更底层的东西。
JIN使得JAVA代码更加优越,但是用起来也不是那么容易的,特别是在规范方面,作为java虚拟机实现的一部分,jni是java应用程序调用原生代码的途径。下面这种图显示了JNI的角色扮演:
OK,知道了JNI的作用我们就开始我们的例子吧,我这里编译jni是在ubunt下编译的,eclipse是在windows下面的开发环境,在ubuntu下配置ndk开发环境请看我前面一篇文章,这里跳过环境配置,这里我们要实现的功能是:
功能:点击一个按钮,吐出来一个toast,toast中的字符串是在jni中传进来的。
这样就演示了如何在java中去调用jni,我这边的jni是使用c语言编写的,也可以使用C++,稍有一点区别,用C++编写我比较喜欢在android BSP源码中编译。
下面首先是android.mk文件,其实就是linux中的makefile文件而已,这里就是说明了一些编译方法以及生成模块的名字。
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- LOCAL_C_INCLUDE := $(LOCAL_PATH)/include
- LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
- LOCAL_MODULE := HelloWorld
- LOCAL_SRC_FILES := \
- HelloWorld.c
- include $(BUILD_SHARED_LIBRARY)
Android.mk的编写也是有规范的。
一个Android.mk file用来向编译系统描述你的源代码。具体来说:该文件是GNU Makefile的一小部分,会被编译系统解析一次或多次。你可以在每一个Android.mk file中定义一个或多个模块,你也可以在几个模块中使用同一个源代码文件。编译系统为你处理许多细节问题。
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。makefile 文件是许多编译器--包括 Windows NT 下的编译器--维护编译信息的常用方法,只是在集成开发环境中,用户通过友好的界面修改 makefile 文件而已。
1、LOCAL_PATH := $(call my-dir)
一个Android.mk file首先必须定义好LOCAL_PATH变量。它用于在开发树中查找源文件。在这个例子中,宏函数’my-dir’, 由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录)。
2、include $( CLEAR_VARS)
CLEAR_VARS 由编译系统提供,指定让GNU MAKEFILE为你清除许多LOCAL_XXX变量(例如 LOCAL_MODULE, LOCAL_SRC_FILES,LOCAL_STATIC_LIBRARIES, 等等...),除LOCAL_PATH 。这是必要的,因为所有的编译控制文件都在同一个GNU MAKE执行环境中,所有的变量都是全局的。
3、LOCAL_MODULE := HcSyncml
LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的,而且不包 含任何空格。注意编译系统会自动产生合适的前缀和后缀,换句话说,一个被命名为'HcSyncml'的共享库模块,将会生成'libHcSyncml.so'文件。
4、LOCAL_C_INCLUDES :=$(LOCAL_PATH)/extra_inc$(LOCAL_PATH)/main_inc
LOCAL_C_INCLUDES 中加入所需要包含的头文件路径
5、LOCAL_SRC_FILES
LOCAL_SRC_FILES中加入源文件路径(需要编译的文件),多个文件用 ‘\’ 隔开
6、LOCAL_LDLIBS+= -L$(SYSROOT)/usr/lib –llog
表示允许打印Log
----------------------------------------------------------------------------------
下面是我们HelloWorld的jni代码:
- //
- //Jay-----HelloWorld
- //HelloWorld.c
- #include <string.h>
- #include <jni.h>
- Jstring
- Java_com_android_jni_HelloWorld_getString(JNIEnv *env,jobject jobj)
- {
- return (*env)->NewStringUTF(env,"HelloWorld! From C!");
- }
很简单吧,2个头文件,大家一看就知道第二个头文件,jni.h里面肯定定义了jni使用的一些库函数,还有jni的一些模板。
JNI的函数名字也是要注意的一个地方,我们这边是:Java_com_android_jni_HelloWorld_getString
Java+package name+class name+function name组成的
-----------------------------------------------------------------------------------
下面是java代码:
- // package name
- package com.android.jni;
- //use inport
- import android.app.Activity;
- import android.content.Context;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class HelloWorld extends Activity {
- /** Called when the activity is first created. */
- Context mContext = null;
- Button bt = null;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- setContentView(R.layout.main);
- mContext = this;
- bt = (Button)findViewById(R.id.button);
- bt.setOnClickListener(new MyButtonListener());
- }
- class MyButtonListener implements OnClickListener{
- public void onClick(View v) {
- if(v.getId() == R.id.button ){
- //调用原生函数得到字符串sre
- String str=getString();
- //吐出message
- Toast.makeText(mContext, str, Toast.LENGTH_SHORT).show();
- }
- }
- }
- //声明jni原生函数
- public native String getString();
- //载入原生库
- static {
- System.loadLibrary("helloworld");
- }
- }
注释在java代码中都有,这边都比较简单,下面我们来运行模拟器。
点击button,会出现HelloWorld! from C!
大功告成!
android jni——helloworld的更多相关文章
- Android jni helloworld
新建Android项目,设置布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android& ...
- Android JNI HelloWorld实现
创建一个JNIDemo的Android工程 在项目下创建一个文件夹jni.(注意必须是jni目录) 在jni目录下创建两个文件:Android.mk 和 first_jni.c(.c文件的名字可以任意 ...
- Android jni简便开发流程
<Android jni helloworld>中介绍了开发jni helloworld的步骤,本文将介绍jni简便开发流程 ① 写java代码 native 声明本地方法 ② 添加本地支 ...
- android JNI调用(转)
Android jni开发资料--NDK环境搭建 android开发人员注意了 谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwi ...
- [转载]—— Android JNI知识点
Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互.JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) 内部运行的 ...
- Android JNI 和 NDK
1.Android NDK 一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第 ...
- Android JNI开发生成.h头文件问题(转)
在JNI开发中,首先要将建立的anroid类编译成.h文件,编译用到命令javah,由于第一次用,以前对java的编译过程也不怎么了解,所以走了好多弯路,网络没有对这一步的详细介绍,这里讲一下: 通过 ...
- Android jni系统变量、函数、接口定义汇总
在做Android jni开发时,jni为我们提供了哪些函数.接口.变量,有时候一头雾水,今天就把jni.h中定义的所有内容列出来,供自己查阅: /* * Copyright (C) 2006 The ...
- Android JNI开发生成.h头文件问题
在JNI开发中,首先要将建立的anroid类编译成.h文件,编译用到命令javah,由于第一次用,以前对java的编译过程也不怎么了解,所以走了好多弯路,网络没有对这一步的详细介绍,这里讲一下: 通过 ...
随机推荐
- Android-Universal-Image-Loader学习笔记(两)--LruDiscCache
最近最少使用缓存官员最近(LruDiscCache)之前,引入一个概念,一个重要的三个班: key:这是DiscCacheAware接口save里面的方法imageUri通过调用参数FileNameG ...
- 在windows server里,对于同一个账号,禁止或允许多个用户使用该账户,同时登录
开始 -> 运行 -> gpedit.msc -> 本地计算机 策略 -> 计算机配置 -> 管理模板 -> Windows 组件 -> 远程桌面服务 -&g ...
- SQL点滴17—使用数据库引擎存储过程,系统视图查询,DBA,BI开发人员必备基础知识
原文:SQL点滴17-使用数据库引擎存储过程,系统视图查询,DBA,BI开发人员必备基础知识 在开发过程中会遇到需要弄清楚这个数据库什么时候建的,这个数据库中有多少表,这个存储过程长的什么样子等等信息 ...
- Python开发工具Wing IDE发布5.0.1版本
Wing IDE是一个跨平台的Python IDE,提供了一个专业代码编辑.自动编辑.自动完成.重构.强大的图形调试器.版本控制.单位测试.搜索及其他功能.目前已经成为最全面.最综合.最先进的智能化P ...
- 深入浅出SQL Server 2008 分区函数和分区表
原文:深入浅出SQL Server 2008 分区函数和分区表 当我们数据量比较大的时候,我们需要将大型表拆分为多个较小的表,则只访问部门数据的查询就可以更快的运行,基本原理就是,因为要扫描的数据变的 ...
- SQLServer通过链接服务器远程删除数据性能问题解决
原文:SQLServer通过链接服务器远程删除数据性能问题解决 在上一遍文章中介绍了SQLServer通过链接服务器访问Oracle性能问题的解决方法,本文介绍链接服务器下远程删除SQLServer数 ...
- 对Extjs中store的多种操作
Store.getCount()返回的是store中的所有数据记录,然后使用for循环遍历整个store,从而得到每条记录. 除了使用getCount()的方法外,还可以使用each()函数,如下面的 ...
- 在线试听功能(前端直接略过吧,适合javaEE后台开发的)
应用场景:录音试听,MP3试听... 比如为客户提供录音功能时.客户希望录音完成试听录音,然后下载等功能.直接上代码:关键是取得录音的在服务器的地址,如:url='http://localhost:8 ...
- Csharp Syntactic sugar
C#语法糖(Csharp Syntactic sugar)大汇总 首先需要声明的是“语法糖”这个词绝非贬义词,它可以给我带来方便,是一种便捷的写法,编译器会帮我们做转换:而且可以提高开发编码的效率,在 ...
- iOS基础 - 多线程线程
一.多线程的应用 l 充分发挥多核处理器的优势,并发(同时执行)执行任务让系统运行的更快.更流畅 二.进程与线程概念 l 一个运行的程序就是一个进程或者叫做一个任务 l 一个进程至少包含一个线程,线程 ...