因为Android程序是用java写的,跑在Dalvik JVM上,而在某些情况下必须要使用到用C++或者C写的代码库,那么就要用ndk开发包来编译这些原生文件,然后才能调用。下文中会提到几个名词:JNI,NDK,Cygwin以及Eclipse工程。
JNI简介
JNI全称为Java Native Interface(JAVA本地调用)。从Java1.1开始,JNI成为java平台的一部分,它允许Java代码和其他语言写的代码(如C&C++)进行交互。并非从Android发布才引入JNI的概念的。
JNI与NDK
简单来说,Android的NDK提供了一些交叉编译工具链和Android自带的库,这些Android的库可以让开发者在编写本地语言的程序时调用。而NDK提供的交叉编译工具链就对已经编写好的C&C++代码进行编译,生成库。
当然了,你也可以自己搭建交叉编译环境,而不用NDK的工具和库。然后生成库,只要规范操作,一样可以生成能让JAVA层成功调用的库文件的。
Cygwin简介
cygwin可以模拟一个windows上的Linux环境。
安装cygwin的时候,默认为在线安装,注意要确保安装了make包,这个很重要,不然后面编译原生代码的时候会出现can't find make类似的错误在cygwin里面。
当出现Select Packages对话框时,搜索“devel”,为了以防万一,把安装选项“default”更改为“install”,安装所以必须的编译工具。然后进入漫长的下载状态,差不多一两个小时,接下来的步骤默认就行。
在home目录下的那个“当前windows用户名下,用文本编辑器打开“.bash_profile”文件,在后面加入如下配置信息
- ndk=/home/Administrator/android-ndk-r7b
- export $ndk
打开cygwin,执行
- cd $ndk
新建一个目录,命名为HelloWorld,然后在里面新建一个名为jni的目录(名称一定要是jni,因为ndk-build的时候会在HelloWorld目录下寻找jni的目录,然后进行build),在jni目录下新建如下文件HelloWorld.c和Android.mk。
HelloWorld.c文件代码如下(此JNI是没有jni_onLoad函数的)
- #include <string.h>
- #include <jni.h>
- jstring
- Java_com_conowen_helloworld_HelloWorldActivity_helloWorldFromJNI( JNIEnv* env,
- jobject thiz )
- {
- return (*env)->NewStringUTF(env, "HelloWorld! I am from JNI !");
- }
- /*注意,这里
- jstring 表示返回值
- Java_com_conowen_helloworld_HelloWorldActivity_helloWorldFromJNI
- 写法是Java+Android工程的包名+Android工程的Activity名+方法名,点号用下划线表示,这个写法很严格。
- 包名:com_conowen_helloworld
- Activity名:HelloWorldActivity
- 方法名:helloWorldFromJNI
- JNIEnv* env, jobject thiz是Native方法自带的参数,可以用来转换一个数据类型。也就是说其实这个helloWorldFromJNI是没有形参的。
- */
Android.mk代码如下
关于Android.mk的编写格式,下一篇博文补全
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
- #LOCAL_MODULE表示生成的库的名字,前面的lib和后缀名不用写
- LOCAL_MODULE := HelloWorld
- LOCAL_SRC_FILES := HelloWorld.c
- include $(BUILD_SHARED_LIBRARY)
然后在终端里面,转到HelloWorld目录下,执行
- $ndk/ndk-build
5、新建一个Android工程
在eclipse里面新建一个Android工程,java代码如下,然后把刚刚生成的libs文件夹拖到Android工程目录下。
- package com.conowen.helloworld;
- import android.app.Activity;
- import android.os.Bundle;
- import android.widget.TextView;
- public class HelloWorldActivity extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- TextView tv = new TextView(this);
- tv.setText(helloWorldFromJNI());
- setContentView(tv);
- }
- public native String helloWorldFromJNI();// native声明,表示这个方法来自Native层。实现过程已经在native层实现了
- static {
- System.loadLibrary("HelloWorld");// 加载库,前面的lib和,后缀名不用写
- }
- }