职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 485|回复: 9

NDK入门、提高和实战

[复制链接]
郁闷小男人 发表于 2011-7-15 11:49 | 显示全部楼层 |阅读模式
     网上也有一些对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文件里面,添加   

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

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;   
}  

public class Point {
        float x;
        float y;
}
  
    然后在c文件中定义一个函数   
C代码  
jfloat Java_chroya_demo_ndk_Main_distance(JNIEnv* env, jobject thiz, jobject a,jobject b){}  

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));   
}  

#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");   
    }   
}  

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
      源码参见附件 。
MyNdkDemo.zip (109.3 KB)
下载次数: 222

hxy 发表于 2011-7-15 11:49 | 显示全部楼层
昨天我装Cygwin 都装了好久,不过最后还是ok了
这个例子讲解的很详细啊

hxy 发表于 2011-7-15 11:49 | 显示全部楼层
这个例子很不错。
     

话说我当年 发表于 2011-7-15 11:50 | 显示全部楼层
还是我写的简单
http://abitno.me/a-simple-tutorial-to-android-ndk

楠楠 发表于 2011-7-15 11:50 | 显示全部楼层
LZ不错,再看andriod java版

找不到我 发表于 2011-7-15 11:50 | 显示全部楼层
最近正在学习NDK,例子很好,容易上手。

有烟没火 发表于 2011-7-15 11:50 | 显示全部楼层
想学一下 环境是windows的 装了个cygin 不知道怎么用 呢

天上智喜 发表于 2011-7-15 11:51 | 显示全部楼层
我是用Cygwin来做的,我是在windows环境下进行开发。
推荐一下 《【eoe特刊】第七期:NDK》

【eoe特刊】第七期:NDK.pdf (4.3 MB)
下载次数: 7


只学java 发表于 2011-7-15 11:51 | 显示全部楼层
跳跃性有点大,讲解不够详细,不过还是非常感谢。


yoyo 发表于 2011-7-19 11:24 | 显示全部楼层
啊...刚回来啊...
您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-4-30 01:57 , Processed in 0.139311 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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