Netbeans玩转ndk

1.       引言

这两天研究了下ndk开发,由于公司android播放器,后续开发须要调用底层so库,网上查了不少资料全都是eclipse,可是我用的是netbeans只好自行研究,ndk很简单,baidu一下资料不少,若是你是一个有经验的程序员,分分钟就能够搞定,编译出一个so来。 html

主要问题就在于如何将soapk打包到一块儿。 java

Eclipse是经过ADT插件自动完成的,也能够本身编写ant脚本,经过ant打包,这就不在本文范围内了。 linux

1.1. 目的

让习惯netbeans的程序员,排斥eclipse的程序员可以顺利的完成他们的android开发,也让像学习ndk开发的人可以快速入门 android

 

1.2. 可能阅读者

VC基础,想搞android开发的开发的技术人员 c++

使用netbeansandroid开发人员(通常也都是VC转过来的,由于VS IDENetbeansIDE风格比较类似) 程序员

2.       开发工具体系

Netbeans 算法

本教程使用的是6.8,但不限于6.8版本(自行下载安装) windows

用于开发android app api

Ndk开发环境: 安全

用于开发供app调用的so本地库

Windows开发环境包含如下2个软件包

n  Ndk开发包android-ndk-r8d-windows.zip

下载连接http://dl.google.com/android/ndk/android-ndk-r8d-windows.zip

若是打不开,能够进入下载页面

http://developer.android.com/tools/sdk/ndk/index.html#download下载

n  Linux模拟环境cygwin

http://www.cygwin.com/

2.1. 搭建安装环境

第2步.         下载Ndk开发包

第3步.         解压到任意位置(本例:F:\ndk)目录结构如图


第4步.         Ndk安装就完成了,该安装cygwin

第5步.         下载cygwin.zip,这个是网络安装器,下载好有900M就不打包在本教程中了

第6步.         安装cygwin,选择第一个,从网上下载安装,如图

                    

第7步.         设置安装目录,如图


第8步.         设置下载到安装文件保存位置,如图


安装完成后,本地就有下载好的包,之后在别的机器从新安装时就能够选择第3项,从本地安装,选者这里设置的目录

第9步.         而后一直默认悬想,一直下一步,到如图步骤,选择一个下载站点,通常选择163速度还能够


第10步.     选择要安装的模块,只要安装Devel就够了,如图


第11步.     等待安装完成吧,大小是900M

第12步.     验证cygwin安装

n  运行安装目录下的“Cygwin.bat”,第一次运行时,它会自动建立用户信息,用户信息存放在“.\Cygwin\home”中。

n  在运行“Cygwin.bat”打开的命令行窗口输入:“cygcheck -c cygwin”命令,会打印出当前Cygwin的版本和运行状态,若是statusok的话,则cygwin运行正常。

n  分别输入:“make –v”和,“gcc –v”命令若是检测成功,会有makegcc相关版本信息打印出来。

如图


第13步.     Ndk开发环境搭建完成

第14步.     在系统环境变量中配置ndk目录(可选的操做,主要是为了方便),如图

cygwinlinux模拟环境,访问windows磁盘的方式是/cygdrive/盘符


2.2. 尝试编译一个so

直接使用附带jni例子

进入目录F:\ndk\\jni目录


编译hello-jni


编译后就会生成so文件了,这个文件就能够供android应用程序调用


 

2.3. netbeans建立的android项目中使用刚才编译出来的so本地库

第1步.         建立android项目calljni

第2步.         添加HelloJni类,代码以下

package com.example.hellojni;

 

public class HelloJni

{

    /* A native method that is implemented by the

     * 'hello-jni' native library, which is packaged

     * with this application.

     */

    public native String  stringFromJNI();

 

    /* this is used to load the 'hello-jni' library on application

     * startup. The library has already been unpacked into

     * /data/data/com.example.hellojni/lib/libhello-jni.so at

     * installation time by the package manager.

     */

    static {

        System.loadLibrary("hello-jni");

    }

}

第3步.         MainActivity类中添加调用代码

    public void onCreate(Bundle icicle) {

        super.onCreate(icicle);

        // ToDo add your GUI initialization code here       

        lib.stringFromJNI();

        TextView  tv = new TextView(this);

        tv.setText( lib.stringFromJNI() );

        setContentView(tv);

}

第4步.         so文件添加到工程目录\lib\armeabi下,添加后so位置如图


第5步.         Netbeans区别于eclipes的关键步骤

1)        编辑F:\ndk\calljni\nbproject\build-impl.xml文件

2)        找到name="-sign"target 也就是执行apkbuildtarget

3)        在全部指令以前,加入如下指令,执行aaptso打包进apk_

<exec executable="${aapt}" failonerror="true">

     <arg value="a"/>

     <arg value="${dist.apk}_"/>

     <arg value="lib/armeabi/libhello-jni.so"/>

</exec>

 

若是有多个so须要打包进去,就多添加几条以上指令

 

这一步就是帮助netbeans的用户解决,如何把so文件打包进apk中这个难题。

你们都知道Apk就是一个zip格式的包,可是你不能直接将so文件打包进编译出来的apk中,由于apk是要签名才有效的,里面有签名文件如图中,打开查看,是经过hash算法计算出来的,因此必须在签名以前,把so文件打包进去一块儿签名,因此必须本身修改项目的编译脚本文件(其实就是ant编译脚本)。

 


 

 

第6步.         编译项目生成calljni.apk,在模拟器运行结果如图


2.4. ndk开发体系相关

1.  什么是NDK

NDK 提供了一系列的工具,帮助开发者快速开发C/C++的动态库(so文件),经过mk 文件隔离CPU、平台、ABI 等差别,开发人员只须要简单修改mk 文件(指出哪些文件须要编译编译特性要求等),就能够建立出so,使你能够在你的Android程序当中用Java语言(JNI)调用这些c/c++代码.

 

Google明确声明该API是稳定的,在后续全部版本中都稳定支持当前发布的API。从该版本的NDK中看出,这些API支持的功能很是有限,包含有:C标准库(libc)、标准数学库(libm)、压缩库(libz)、Log库(liblog

2.  so文件必须使用ndk编译?

不是,能够直接在linux下编译so,可是你得确保你所使用的api是操做系统所支持,就是上面google声明中说的ndk支持的库,若是是特定平台支持的api,那可能就只有部分手机能够正常运行

3.  mk文件如何编写

附件提供mk模板一分,可参考编写

4.  网上说的使用javah生成c/c++ .h文件,是否必须

不是,彻底不须要,给出java生成.h文件的指令,和先决条件

javah -classpath ./build/classes -d jni org.me.calljni.MainActivity

首先必须编译java类,无论你用任何方式,编译出来就行,生成类.class文件,

而后使用以上指令生成头文件-classpath后面的目录就是生成的class的目录

5.  java代码、c代码、so方法之间的联系

n  你的应用的java源代码中要声明一个或多个方法,这些方法前面需有'native'关键字,这代表它们被本地代码实现。如:

public native String  stringFromJNI();

n  你必须提供本地的共享库(.so),库中包含这些方法的实现。将这个库打包你的.apk中。这个库的命名必须符合标准的Unix命名规则,也就是:lib<something>.so这种形式,例如:

libhello-jni.so

n  而且还要包含一个标准的JNI入口,例如:

static {

        System.loadLibrary("hello-jni");

    }

n  c函数生命应该按照以下规则命名,以说明函数是属于哪一个java类的

java_目录_目录_方法名()例如:

 

jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )

以上函数,是一个java类的成员函数,这个类必须是在com\example\hellojni包下,类名必须是HelloJni

方法名必须是stringFromJNI(),没有参数

这是由于java是面向对象的语言,因此so中实现的全部全局函数应该是java的某个成员方法

 

n  JNIEnv* env, jobject thiz

2个参数是全部jni函数必须的,只有这2个参数的函数,表示无参数的成员函数,带有 3个参数就表示成员函数有1个参数,依次类推

 

n  JNIEXPORTJNICALL在提供android应用调用的so代码中不是必须的

加上兼容性更好

JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,jobject thiz );

6.  ndk能不能直接开发java

不知道,未研究,有兴趣的能够深刻研究,可以实现类成员函数,已经足够

7.  so中能不能调用其它 .so.a

理论上能够,但未验证,能够自行验证,若是是so,须要将so文件一块儿打包进apk,若是是.a文件,应该不须要打包进apk

8.  ndk适合开发哪些模块

如下为我的理解

n  首先ndk未提供ui以及事件处理的api,因此作android开发不可能使用纯c/c++,应用主体应该仍是android sdk使用java开发

n  其次so的反编译难度比android应用的java代码要难上不少,,因此ndk能够用于开发一些须要保密代码,防止反编译泄露机密算法逻辑等

n  观察ndk支持的库,能够看到,ndk适合作一些算法模块,提升效率,支持libc也能够实现通讯模块,增强通讯的安全性

相关文章
相关标签/搜索