NDK入门、提高和实战 博客分类: Android AndroidLinuxJNIEclipseC#

    网上也有一些对NDK的介绍,不过都是很简单的把sample里面的例子讲解一下,并不深入,我这里把我的所得分享一下。我下载的是Android Native Developer Kit (NDK) R4版本,当前的最新版。     下载地址如下: http://dl.google.com/android/ndk/android-ndk-r4b-linux-x86.zip

  我下面讲的都是以linux环境为准,因为我的系统是linux的。windows下可以弄个Cygwin,模拟linux环境,网上有很多介绍。     首先进入ndk目录,有个README文件,里面提到了API的文档在docs/STABLE-APIS.TXT里面,如何安装NDK,参考docs/INSTALL.TXT,还有如何使用NDK,参考docs/HOWTO.TXT。建议这些文档都看一遍,有个大概了解。

安装:     INSTALL.TXT里面讲的是如何安装,安装NDK,就需要一个可以make环境,linux自带了,所以不用关心。还有一点,以前的版本都需要运行build/host-setup.sh来进行初始化,这个版本把它删除了,这样更方便。     然后就是配置环境变量。     在~/.bashrc文件里面,添加   

NDK_ROOT=~/android-ndk-r4b #后面的路径是NDK所在的目录,根据自己的目录修改
export NDK_ROOT

    然后保存,重新打开bash。

使用:     先拿sample试刀吧,刚开始什么都不知道,只有运行出一个例子,才能增加信心。     编译的两种方法:     1.进入要目标工程目录,比如$NDK_ROOT/samples/hello-jni,然后执行$NDK_ROOT/ndk-build     2.在任何地方,执行$NDK_ROOT/ndk-build -C $NDK_ROOT/samples/hello-jni.     如果成功的话,会生成obj和libs两个目录。     选择一种方法,编译这个例子。然后打开eclipse,把hello-jni这个工程导入,运行,ok,就能看到效果了。

进阶:     docs下的STABLE-APIS.TXT里面讲了系统API的用法。我以1.5为例。进入$NDK_ROOT/build/platforms/android-3/arch-arm/usr/include,里面有很多.h文件,这些都是可以在NDK里面调用的,除了linux和asm目录下的。     一般来说,主要用到的是jni.h,里面提供了很多对类和对象的操作。     另外,1.5提供了log的API,在android/log.h里面,使用的时候,在c文件中#include <android/log.h>,然后在Android.mk里面加上LOCAL_LDLIBS := -llog,就可以了。     1.6到2.01提供了openGL ES 1.x的API,2.1提供了openGL ES 2.0的API,2.2提供了graphics的处理接口。使用方法同log。

实例:     给出两个点的坐标,求它们的距离。     首先,创建一个Point对象,

public class Point {
	float x;
	float y;
}

    然后在c文件中定义一个函数   

jfloat Java_chroya_demo_ndk_Main_distance(JNIEnv* env, jobject thiz, jobject a,jobject b){}

    返回值是float,在jni中定义的是jfloat。

    函数名规则: Java开头,接着是包名的每一段,然后是类名,最后是Java中调用的方法名,中间都用下划线隔开。第一个参数JNIEnv* env和第二个参数jobject thiz都是必须的,后面的才是Java中传递进来的参数。这里是两个Point对象。

    首先确定要做的步骤:     1.找到这个Point类     2.找到类中的域x和y的域id     3.根据ID取出x和y的值     4.计算结果并返回     那么代码如下:

#include <jni.h>
#include <math.h>
#include <android/log.h>

jfloat Java_chroya_demo_ndk_Main_distance(JNIEnv* env, jobject thiz, jobject a,jobject b)
{
        //步骤1
	jclass point_class = (*env)->FindClass(env, "chroya/demo/ndk/Point");
	if(point_class == NULL) {
		//printf("class not found");
		__android_log_write(ANDROID_LOG_INFO, "MyNdkDemo", "class Point not found");
		return 0;
	} else {
		__android_log_write(ANDROID_LOG_INFO, "MyNdkDemo", "found class Point");
	}
        //步骤2
	jfieldID field_x = (*env)->GetFieldID(env, point_class, "x", "F");
	jfieldID field_y = (*env)->GetFieldID(env, point_class, "y", "F");
        //步骤3
	jfloat ax = (*env)->GetFloatField(env, a, field_x);
	jfloat ay = (*env)->GetFloatField(env, a, field_y);
	jfloat bx = (*env)->GetFloatField(env, b, field_x);
	jfloat by = (*env)->GetFloatField(env, b, field_y);
        //步骤4
	return sqrtf(powf(bx-ax, 2) + powf(by-ay, 2));
}

    然后在Java里面调用:

public class Main extends Activity {
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView tv = new TextView(getApplicationContext());
        Point a = new Point();
        a.x = 3;
        a.y = 3;
        
        Point b = new Point();
        b.x = 5;
        b.y = 5;
        
        float d = distance(a,b);
        tv.setText("distance(a,b):"+d);
        setContentView(tv);
    }
    
    public native float distance(Point a, Point b);
    
    static {
    	System.loadLibrary("demo");
    }
}

      运行,得到结果distance(a,b):2.828427

      源码参见附件 。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏JavaEdge

Bean Validation 介绍及最佳实践关于 Bean ValidationBean Validation 中的 constraint创建一个包含验证逻辑的简单应用(基于 JSP)定制化的 co

31670
来自专栏技术碎碎念

Jsp语法、指令及动作元素

一、JSP的语法 1、JSP的模板元素:(先写HTML)    就是JSP中的那些HTML标记    作用:页面布局和美化 2、JSP的Java脚本表达式:  ...

46060
来自专栏JackieZheng

照虎画猫写自己的Spring——依赖注入

前言 上篇《照虎画猫写自己的Spring》从无到有讲述并实现了下面几点 声明配置文件,用于声明需要加载使用的类 加载配置文件,读取配置文件 解析配置文件,需要将...

21880
来自专栏Charlie's Road

<Solidity学习系列四>使用编译器

Solidity存储库的一个构建目标是solc,solidity命令行编译器。 使用solc --help为您提供所有选项的解释。 编译器可以生成各种输出,范围...

17120
来自专栏王磊的博客

Spring Boot(十二)单元测试JUnit

JUnit是一款优秀的开源Java单元测试框架,也是目前使用率最高最流行的测试框架,开发工具Eclipse和IDEA对JUnit都有很好的支持,JUnit主要用...

11020
来自专栏枕边书

PHP递归创建多级目录(一道面试题的解题过程)

今天看到一道面试题,要写出一个可以创建多级目录的函数: 我的第一个感觉就是用递归创建,具体思路如下: function Directory($dir){   ...

30070
来自专栏xdecode

Spring之IOC

IOC 控制反转, 将由程序直接操控的对象调用权交给容器, 通过容器来实现对象的装配和管理. 容器即applicationContext.xml 第一个spri...

21170
来自专栏我就是马云飞

设计模式二十四章经之责任链模式

14730
来自专栏清晨我上码

spring boot 使用ReloadableResourceBundleMessageSource的坑

所以我们重点关注的AbstractMessageSource的getMessage方法。以其中一个为例分析

69320
来自专栏大内老A

我所理解的Remoting(3):创建CAO Service Factory使接口和实现相互分离

我们知道对于Remoting,有两种不同的Activation模式:Server Activation和Client Activation。他我在前面的系列文章...

21460

扫码关注云+社区

领取腾讯云代金券