感谢支持
我们一直在努力

Ubuntu NDK Demo

前面文章介绍了 Ubuntu 安装 GNU Toolchain for ARM,有了这个交叉编译工具主要是为了Android的移植做了准备。下面介绍Android中的NDK开发。


1、从这里下载最新版的NDK,现在最新版名字是android-ndk-r5b-linux-x86.tar.bz2.tar,解压,解压后名字为android-ndk-r5b,接下来设置PATH环境变量:export PATH=$PATH:/home/stone/android-ndk-r5b,设置该环境变量是因为等会在android-ndk-r5b目录下的ndk-build程序要被用到;


2、上面这样就配置好了NDK的开发环境,接下来就创建一个项目来测试一下,步骤如下:


1)、使用Eclipse创建一个Android项目,名字为“HelloNDKJNI”,Build Target设置为“Android 2.2”,Application Name设置为“HelloNdkJni”,Package Name设置为“com.stone”,Create Activity设置为“.HelloNdkJni”,Min SDK Version设置为“8”;2)、接下来创建C语言库,在Eclipse的Package Explore里面的HelloNDKJNI项目下创建目录“jni”,并在该目录下创建两文件“Android.mk”和“hello-ndk-jni.c”,如下图所示:


Ubuntu NDK Demo


Android.mk文件内容如下:


LOCAL_PATH := $(call my-dir)


include $(CLEAR_VARS)


LOCAL_MODULE    := hello-ndk-jni


LOCAL_SRC_FILES := hello-ndk-jni.c


include $(BUILD_SHARED_LIBRARY)


hello-ndk-jni.c文件内容如下:


#include


#include


//注意这里是又规则的


jstring Java_com_stone_HelloNdkJni_stringFromNDKJNI( JNIEnv* env,jobject thiz )


{


return (*env)->NewStringUTF(env, “Hello from NDK JNI !”);


}


3)、编译创建的C库,打开终端,进行步骤1中的设置PATH环境变量操作(如果有进行,则可跳过),进入到创建的HelloNDKJNI项目中的jni目录,执行命令ndk-build,此时会在项目中生成libs和obj目录,并在里面生成相应的文件,运行结果如下图所示:


Ubuntu NDK Demo


4)刷新Eclipse中的Package Explore中的HelloNDKJNI项目,此时obj和libs目录也添加进去了,在obj/armeabi分支下也多了libhello-ndk-jni.so文件,hello-ndk-jni这个名是根据2-2)步中的Android.mk文件中的LOCAL_MODULE决定的,接下来修改src/com.stone分支下的HelloNdkJni.java文件,最后的文件内容如下:


package com.stone;


import android.app.Activity;


import android.os.Bundle;


import android.widget.TextView;


public class HelloNdkJni extends Activity {


@Override


public void onCreate(Bundle savedInstanceState) {


super.onCreate(savedInstanceState);


TextView tv =new TextView(this);


tv.setText(stringFromNDKJNI());


setContentView(tv);


}


public native String stringFromNDKJNI();


static{


System.loadLibrary(“hello-ndk-jni”);


}


}


更多的NDK例子,可以参考第1步中解压后目录下的samples目录下的项目。


参考见http://www.linuxidc.com/Linux/2011-04/35239p2.htm

NDK入门、提高和实战


网上也有一些对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文件里面,添加



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

  2. 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对象,



  1. public class Point {   

  2.     float x;   

  3.     float y;   

  4. }  

然后在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.计算结果并返回


那么代码如下:



  1. #include <jni.h>   

  2. #include <math.h>   

  3. #include <android/log.h>   

  4.   

  5. jfloat Java_chroya_demo_ndk_Main_distance(JNIEnv* env, jobject thiz, jobject a,jobject b)   

  6. {   

  7.         //步骤1   

  8.     jclass point_class = (*env)->FindClass(env, “chroya/demo/ndk/Point”);   

  9.     if(point_class == NULL) {   

  10.         //printf(“class not found”);   

  11.         __android_log_write(ANDROID_LOG_INFO, “MyNdkDemo”“class Point not found”);   

  12.         return 0;   

  13.     } else {   

  14.         __android_log_write(ANDROID_LOG_INFO, “MyNdkDemo”“found class Point”);   

  15.     }   

  16.         //步骤2   

  17.     jfieldID field_x = (*env)->GetFieldID(env, point_class, “x”“F”);   

  18.     jfieldID field_y = (*env)->GetFieldID(env, point_class, “y”“F”);   

  19.         //步骤3   

  20.     jfloat ax = (*env)->GetFloatField(env, a, field_x);   

  21.     jfloat ay = (*env)->GetFloatField(env, a, field_y);   

  22.     jfloat bx = (*env)->GetFloatField(env, b, field_x);   

  23.     jfloat by = (*env)->GetFloatField(env, b, field_y);   

  24.         //步骤4   

  25.     return sqrtf(powf(bx-ax, 2) + powf(by-ay, 2));   

  26. }  

然后在Java里面调用:



  1. public class Main extends Activity {   

  2.       

  3.     @Override  

  4.     public void onCreate(Bundle savedInstanceState) {   

  5.         super.onCreate(savedInstanceState);   

  6.         TextView tv = new TextView(getApplicationContext());   

  7.         Point a = new Point();   

  8.         a.x = 3;   

  9.         a.y = 3;   

  10.            

  11.         Point b = new Point();   

  12.         b.x = 5;   

  13.         b.y = 5;   

  14.            

  15.         float d = distance(a,b);   

  16.         tv.setText(“distance(a,b):”+d);   

  17.         setContentView(tv);   

  18.     }   

  19.        

  20.     public native float distance(Point a, Point b);   

  21.        

  22.     static {   

  23.         System.loadLibrary(“demo”);   

  24.     }   

  25. }  

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


源码下载在Linux公社的1号FTP服务器里,下载地址:


FTP地址:ftp://www.linuxidc.com


用户名:www.linuxidc.com


密码:www.muu.cc


在 2011年LinuxIDC.com\4月\Ubuntu NDK Demo


下载方法见 http://www.linuxidc.net/thread-1187-1-1.html

赞(0) 打赏
转载请注明出处:服务器评测 » Ubuntu NDK Demo
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏