标签:anroid ndk开发
Java 层与 C 层之间会有密切的沟通。此时 JNI(Java Native Interface) 就 扮演双方沟通的接口了。
藉由 JNI 接口,可将 Java 层的类别的函数实现部份移到本地的 C 函数中。
理由是: Java 程序码执行速度较慢,而 C 程序码执行速度快。而更具有商业价值,
有许多既有的 C( 或 C++) 程序模块,透过 JNI 接口能轻易地将 Java 程序与 C模块衔接起来了。
但是, Java 程序码可以跨平台,而 C 程序码与本地平台设备息息相关,所以称为本地 (Native) 程序码。
所以,在设计整个应用软件时,通常会从执行速度、跨平台能力等不同角度来做评估,以便取得最合乎需要的规划。
http://wear.techbrood.com/tools/sdk/ndk/index.html
早在2014的6月份,山景城就宣布了即将到来的Android L将会获得64位处理器的支持。
几周后,修订的NDK(Native Development Kit,原生开发工具包)的10版发布了,它支持三个64位架构的芯片,
即arm64-v8a、x86_64与mips64。相信开发者们都知道,当arm64-v8a、x86_64与mips64三种64位芯片都有了支持后,
实际上,你就能这么想了,有了这三种新的ABI应用系统二进制接口的支持,
也就算是所有的64位芯都将能够运行新版本的Android了。
随着Android L的正式发布越来越近,Google近日更新了NDK到10b版,
新的NDK r10b添加了一个新的Intel 64位芯片的Emulator模拟器镜像,
从这点上讲,应用程序开发人员可以为使用Intel 64位芯片的Android设备准备或仿真应用了。
由于Intel的手持移动平台的芯片一直都不温不火的,该公司一直都在积极地为Android开发人员布置他们的架构。
山景城新的NDK的发布显然有助于Intel自家的架构布局。由于Intel芯片性能的强大,
开发人员可能会喜欢或有一定的兴趣在此平台上开发一些好的应用,
尤其是游戏。另外,从另一方面讲,这也是一种迹象,Intel和Google正在培养更强更紧密的合作关系。
兼如这种关系,我们可以期待,在不久的将来,将会有更多的关于采用Intel Atom/Bay Trail芯片的Android设备。
请注意,NDK只为本地应用程序服务,而不为围绕Java构建的标准Android SDK服务。
如果你是一名开发人员,然后你一直期待将自己的应用程序运行在64位环境中,
或者如果你需要更新到最新版本的NDK,NDK r10b自当是你的妙选
你能去源文的Android NDK开发者中心下载,或者你能直接地从我们提供的链接启动下载。
android-ndk64-r10b64 位 ABI (Application Binary Interface)的默认编译器为 GCC 4.9,
最低支持 API 等级(API Level)为 Android L 的 更新等级(Android 4.4 的 API Level 为 19,新版本应为 20)。
此外,新的 CPU 特征库添加 ARM v8 架构机器内核支持,
以修正现有库可能无法检测到 ARM v8 NEON 解码芯片的问题。其它具体更新和下载地址见官方发布说明。
ubuntu14.04 64bit ,
解压:tar -xvf android-ndk64-r10b-linux-x86_64.tar.bz2
修改 ~/.bashrc文件:在文件最后添加如下语句:
export PATH=/home/zshh/home/android-ndk-r10b:$PATH
进入/android-ndk-r10b/samples/hello-jni/jni$里面
android-ndk-r10b/samples/hello-jni/jni$ ndk-build 如果生成如下信息,表示在
[arm64-v8a] Compile : hello-jni <= hello-jni.c
[arm64-v8a] SharedLibrary : libhello-jni.so
[arm64-v8a] Install : libhello-jni.so => libs/arm64-v8a/libhello-jni.so
[x86_64] Compile : hello-jni <= hello-jni.c
[x86_64] SharedLibrary : libhello-jni.so
[x86_64] Install : libhello-jni.so => libs/x86_64/libhello-jni.so
[mips64] Compile : hello-jni <= hello-jni.c
[mips64] SharedLibrary : libhello-jni.so
[mips64] Install : libhello-jni.so => libs/mips64/libhello-jni.so
[armeabi-v7a] Compile thumb : hello-jni <= hello-jni.c
[armeabi-v7a] SharedLibrary : libhello-jni.so
[armeabi-v7a] Install : libhello-jni.so => libs/armeabi-v7a/libhello-jni.so
[armeabi] Compile thumb : hello-jni <= hello-jni.c
[armeabi] SharedLibrary : libhello-jni.so
[armeabi] Install : libhello-jni.so => libs/armeabi/libhello-jni.so
[x86] Compile : hello-jni <= hello-jni.c
[x86] SharedLibrary : libhello-jni.so
[x86] Install : libhello-jni.so => libs/x86/libhello-jni.so
[mips] Compile : hello-jni <= hello-jni.c
[mips] SharedLibrary : libhello-jni.so
[mips] Install : libhello-jni.so => libs/mips/libhello-jni.so
上面输出的信息,表示的生个各个平台需要的动态库文件。
如果需要修改,在真实环境下,可能不需要生成这么多中。我们可以需要的只是其中一种。
比如x86_64,或则armeabi-v7a ,那么我么需要修改文件
查看下该文件下的文件。
zshh@HP:~/Downloads/android-ndk-r10b/samples/hello-jni/jni$ ls
Android.mk Application.mk hello-jni.c
我们需要打开Application.mk文件.
zshh@HP:~/Downloads/android-ndk-r10b/samples/hello-jni/jni$ vim Application.mk
将APP_ABI := all 改成APP_ABI := armeabi-v7a
这样生成的就只会生个armeabi-v7a架构下的代码了。
/***HelloNdk.java*****/
package com.octopus.com; public class HelloNdk { static{ System.loadLibrary("HelloNdk"); } public native String sayHello(); }
package com.octopus.com; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); HelloNdk obj = new HelloNdk(); String str = obj.sayHello(); setTitle("["+str+"]"); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
使用javah工具生成c的头文件
zshh@HP:~/work/android/workspace/NDK/jni$ javah -classpath ../bin/classes com.octopus.com.HelloNdk
1.jni目录说明:我们需要再eclipse工程中jni目录,如何使用cd命令切换到该目录。
2.使用javah -classpath 命令找到我们HelloNdk.class文件所在的目录,生成相应的头文件。
3.当执行完成javah -classpath ../bin/classes com.octopus.com.HelloNdk命令之后。刷新这个NDK项目,
会在该目录下生成com_octopus_com_HelloNdk.h。
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_octopus_com_HelloNdk */ #ifndef _Included_com_octopus_com_HelloNdk #define _Included_com_octopus_com_HelloNdk #ifdef __cplusplus extern "C" { #endif /* * Class: com_octopus_com_HelloNdk * Method: sayHello * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_octopus_com_HelloNdk_sayHello (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif4. 该头文件必须包含#include<jni.h>头文件。
5. 注释部分的函数如下:Class:是完成包路径和类名组成。也就是我们/com/octopus/com/HelloNdk这个类的路径
但是这里使用下划线隔开分隔:com_octopus_com_HelloNdk
6. Method:方法名。sayHello
7.方法签名: ()Ljava/lang/String; 从这个我们可以看出该方法没有参数。它的返回值的类型是String类型。
(*********注释: 这部分涉及到JNI的规范我们稍后在做介绍。)
8.再jni目录下实现com_octopus_com_HelloNdk.c
#include <jni.h> /* * Class: com_octopus_com_HelloNdk * Method: sayHello * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_octopus_com_HelloNdk_sayHello (JNIEnv *env, jobject obj){ return (*env)->NewStringUTF(env,"Hello, Ndk ...\n"); }9.编译生成 .so文件。
编写Android.mk文件如下:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := HelloNdk LOCAL_SRC_FILES := com_octopus_com_HelloNdk.c include $(BUILD_SHARED_LIBRARY)
10.部署测试,效果如图:
标签:anroid ndk开发
原文地址:http://blog.csdn.net/shaohuazuo/article/details/42873267