JNI – Java Native Interface: Java平台中一个用于和本地C代码进行互操作的API,称为Java本地接口。也就是用来实现java程序中调用C函数。实质是将本地C代码编译到一个动态装载库中(如libHello.so/Hello.dll)。
Android JNI: 在Android工程中调用C的过程,称为Native Development。
本文档通过在Android APP中调用C函数执行Liniux 的Shell命令来简单介绍一下Native Development。
一、 准备
1、OS:Windows
2、Eclipse:略。
3、NDK(Native Development Kit):用来将C/C++生成的原生代码库嵌入到.apk文件中。下载地址:android-ndk-1.6_r1 ,解压即可。此外,NDK中还包含了从C / C++生成原生代码库所需要的工具和build files。要执行这些build,需要借助下面的Cygwin工具。
4、 Cygwin:是一个在windows平台上运行的unix模拟环境,使用gnu工具集在windows上进行嵌入式系统开发的优秀工具。下面着重介绍其安装方法:
首先下载安装工具:http://www.cygwin.com/setup.exe
点击执行它,下面是几个关键步骤的截图:
点击下一步 –> 选择Install from Internet –> 下一步 –>选择安装目录 –> 下一步 –> 选择下载文件存放的目录 –> 下一步 –> 选择上网代理:Use Internet Explorer Proxy Settings –> 下一步出现下图:
选择一个下载网站,通过测试,从http://mirrors.163.com下载速度较快,如果列表中没有,可以Add进去。
然后点击下一步,就进入了一个漫长的阶段Downloading,完成后会出现下图:
将箭头指向的Devel@Default点成install然后下一步, 又进入一个漫长的阶段,包括解包,Checking,Running…
好几个小时后,该阶段结束,直接下一步点击完成安装。桌面出现图标:
点击测试,如果出现下图,则表示安装成功:
接下来用Cygwin执行NDK/build下的host-setup.sh完成NDK的安装。方法:在窗口中通过cd命令进入NDK目录,然后执行build/host-setup.sh.
user@lizq /cygdrive/e/eclipse/android-ndk-1.6_r1
$build/host-setup.sh
出现以上信息表示 Host setup complete。可以先编译一下NDK/apps文件夹中的工程实例,检查NDK是否正常工作.
选择apps/hello-jni做实验, 在NDK根目录下执行:make APP=hello-jni -B,其中-B参数是始终执行build, 不管C/C++代码是否有修改。如下图:
从执行结果中可以看到:
SharedLibrary : libhello-jni.so
Install : libhello-jni.so => apps/hello-jni/project/libs/armeabi
生成了一个动态装载库libhello-jni.so,并且在libs/目录下NDK新建了一个armeabi文件夹,然后把libhello-jni.so放进去。
二、工程实践 – MyJni
1. 在NDK/apps/目录下新建一个文件夹:MyJni
2. 在MyJni下新建一个文件夹:project,用来存放实际工程
3. 在MyJni下新建一个文件:Application.mk, 内容如下:
APP_PROJECT_PATH := $(call my-dir)/project
APP_MODULES := Hello #最终.so文件的名字,如(Hello对应libHello.so)
4.在Eclipse中新建一个Android工程,Location选择上面的../apps/Myjni/project
5. 代码:
HelloJni.java
package com.jni.hello;
public class HelloJni {
public native String cmd(String c);
}
执行javac HelloJni.java -> 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: cmd
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_ HelloJni_cmd
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
注意几个地方jstring和Ljava/lang/String;
在C和Java之间传递数据时,应该知道彼此之间的对应类型。如jstring 对应Ljava/lang/String;
6. 在project/目录下新建一个文件夹:jni,用来存放C/C++文件,把上面的HelloJni.h放进去。
7. 实现HelloJni.c
#include “HelloJni.h”
JNIEXPORT jstring JNICALL Java_HelloJni_cmd(JNIEnv * env, jobject obj, jstring cmd)
{
//略,参考附件源代码
}
8. 在jni目录下新建一个Android.mk, 内容如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Hello #最终.so文件的名字,如(Hello对应libHello.so)
LOCAL_SRC_FILES := HelloJni.c
LOCAL_LDLIBS += -llog
include $(BUILD_SHARED_LIBRARY)
9. 用Cygwin编译生成动态装载库
打开Cygwin,cd进入NDK目录,如/cygdrive/e/eclipse/android-ndk-1.6_r1
执行make APP=MyJin,如图:
生成了libHello.so,并被放到../libs/armeabi目录下。
10. 在Android工程中调用JNI,如下Hello.java 代码片段:
public class Hello extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//…
System.loadLibrary("Hello"); //对应libHello.so
HelloJni hjni = new HelloJni();
String cmd = “cat /proc/meminfo”; //shell 命令,查看内存信息
_tv.setText("excute " + cmd + "\n" + hjni.cmd(cmd)); //在界面上显示执行结果
setContentView(_tv);
}
}
11. 模拟器运行结果:
12.源代码及工具包
参考附件。
三、 总结/问题
本文档是Android工程使用JNI之实践的初级篇,许多地方都是按部就班,比较死板。像
下面的一些问题都没有做深入的研究。
1. 为什么一定要把工程放在NDK/apps/下?
2. 如果工程的目录结构变化了,该如何写Application.mk和Android.mk?
能否将Cygwin和NDK都“集成”到Eclipse中,实现一键编译?
相关推荐
"传智播客_Andorid_JNI视频_day01视频"很可能是对这一主题的初级教程,旨在帮助开发者入门JNI编程。 JNI的核心是提供了一种方式,让Java代码能够声明和调用本地方法,这些方法由非Java语言(如C、C++)实现。这涉及...
Android初级开发者:在本书指引下阅读代码,搭建系统开发环境,对于Android应用程序的开发者,重点关注后3章的内容。 Android中、高级开发者:通过本书的引导,学习系统架构,关注开发要点,并尽量使用手机系统...
《Android应用开发揭秘》全部实例源代码,配合《Android应用开发揭秘》使用 前言 第一部分 准备篇 第1章 Android开发简介 1.1 Android基本概念 1.1.1 Android简介 1.1.2 Android的系统构架 1.1.3 ...
Android进阶初级:组件Widget/ 菜单Menu/ 布局Layout 详解 Xml解析(Pull/Dom/Sax)/JNI 解析SQL数据库原理, SQLit e /SharedPreferences/File详解 多媒体Audio/Video/Camera 详解 Android进阶高级:蓝牙/WIFI SMS/...
16.3.1 JNI接口设计 16.3.2 使用C\C++实现本地 方法 16.3.3 Android.mk实现 16.3.4 Application.mk实现 16.3.5 编译C\C++代码 16.4 AndroidNDK中使用0penGL 16.5小结 第17章 Android脚本环境 17.1 Android脚本环境...
16.3.1 JNI接口设计 16.3.2 使用C\C++实现本地方法 16.3 编译C\C++代码 16.4 AndroidNDK中使用0penGL 16.5小结 第17章 Android脚本环境 17.1 Android脚本环境简介 17.2 Android脚本环境安装 17.3...
在Android开发领域,不同的开发者根据其技能水平被划分为不同的等级:初级、中级、高级以及顶级。这些等级不仅反映了开发者的技术能力,也代表了他们在职业道路上的成长阶段。接下来,我们将深入探讨每个等级的具体...
从这份文档中,我们可以提炼出一系列关于Android学习与开发的关键知识点,这些内容不仅涉及了作者对Android系统的理解和评价,还涵盖了其个人的学习经历、技术成长路径以及对Android开发的深入探讨。 ### Android与...
这本书旨在帮助读者从初级阶段跨越到高级阶段,掌握更深层次的Android技术和实践。通过对这本书的学习,开发者可以提升自己的专业技能,为职业生涯的进一步发展打下坚实的基础。 在Android的进阶学习中,有几个关键...
杨丰盛,Android应用开发先驱,对Android有深入研究,实战经验极其丰富。精通Java、C、C++等语言,专注于移动通信软件开发,在机顶盒软件开发和MTK平台软件开发方面有非常深厚的积累。2007年获得中国软件行业协会...
使用UVC Camera框架的时候... 关键点在于 libuvccamera 依赖库中的 android_usbfs.c 中 handle_iso_completion (struct libusb_device_handle *handle, struct usbi_transfer *itransfer, struct usbfs_urb *urb)方法中
第5章“Android的Java虚拟机和Java环境”,这是介于本地和Java层之间的相关内容,主要介绍Android的Java虚拟机Dalvik的基本概念、Android Java程序的环境、JNI的使用方法,以及Java框架的启动流程等。 第6章...
总之,《Android内核剖析》的资源包提供了深入理解Android系统内部运作的机会,无论是对于初级开发者还是经验丰富的工程师,都有极大的学习价值。通过学习和实践这些知识点,可以提升Android开发技能,解决实际问题...
7. **《Android开发艺术探索》**:这本书不仅讲解UI、框架的使用,还深入剖析了View工作原理、事件体系、性能分析和动画、JNI等内容,有助于提升开发者对Android开发的深入理解。 8. **《Android设计模式源码分析》...
- **Java Native Interface (JNI)**:了解如何通过JNI在Android中调用C/C++代码,这对于提高游戏性能至关重要。 - **OpenGL ES**:作为Android平台上的标准3D图形API,本书详细介绍了如何使用OpenGL ES进行高效3D...
2. **Android 图像处理篇**(第02期):这期特刊深入探讨了Android中的图像处理技术,可能包括Bitmap对象的使用、图片资源的加载优化、OpenGL ES用于图像处理等方面。这对于希望提升应用视觉效果或者进行游戏开发的...
第5章“Android的Java虚拟机和Java环境”,这是介于本地和Java层之间的相关内容,主要介绍Android的Java虚拟机Dalvik的基本概念、Android Java程序的环境、JNI的使用方法,以及Java框架的启动流程等。 第6章...
这个"NDKDemo入门"就是针对Android NDK的初级实践,旨在介绍如何调用C语言实现的代码,通过JNI(Java Native Interface)与Java层进行通信。 首先,我们需要了解JNI。JNI是Java平台的标准接口,它允许Java代码和...