Android NDK开发入门指引(有源码)
2011-02-16 20:03
393 查看
Android NDK
开发入门指引
前言:
AndroidNDK
是一套工具,允许
Android
应用开发者嵌入从
C
、
C++
源代码文件编译来的本地机器代码到各自的应用软件包中
,
并通过
JNI
进行访问。
Android
从
1.5
开始支持
NDK.
环境搭建:
NDK开发需要安装以下物体
:
1.cygwin
(
需要
1.7
以上版本,下载地址:
http://www.cygwin.com
官方明确表示
MSys or Cygwin 1.5 is not
supported),
这个我用的是在线安装方法(并且是全安装,非常大,很耗时)
安装好后启动
cygwin,
运行
:
Make –v
看到如下所示就
ok
了
(
注意
:GNU Make
要
3.81
以上版本
)
2.NDK
(android-ndk-r4b)
,此文档只针对
r4b
版进行说明
, ndk
可以到官方网
http://developer.android.com
上进行下载,
但这个网站已被
zf
和协,我是在这里下载:
http://d131.d.iask.com/fs/800/1/c1631bdc5eaf7b8309db9cb23311693035788482/zip/android-ndk-r4b-windows.zip
,
如下载不了,直接向我要吧
.
Ndk
下载下来随意解压到一个目录即可
(
路径中不能有空格
)
如
: D:/android/android-ndk-r4b
然后为
cygwin
配好我们的
ndk PATH
环境
在
cygwin
用户路径
C:/cygwin/home/huangdingwu (
请替换相应用户名
)
打开
.bash_profile
在文件末尾加上:
ANDROID_NDK_ROOT=/cygdrive/d/android/android-ndk-r4b
export ANDROID_NDK_ROOT
PATH=${ANDROID_NDK_ROOT}:${PATH}
配好后重新打开
cygwin
输入:
Ndk-build
如出现如下提示表示路径已配好:
3.eclipse +
android sdk
(
这个
…
大家应该都已经安装好了
)
4.windows
中
Jdk
安装配置
第一步:下载
JDK
JDK
是
Java Developement Kit
的缩写,包括
Java
编译器和运行时环境
j2re
,
可以从
SUN Java
站点下载
http://java.sun.com/javase/downloads/index.jsp http://www6.software.ibm.com/dl/idpe/idpe-p?S_TACT=104AHW02
或它的前一面:
http://www-106.ibm.com/developerworks/java/jdk/eclipse/
第二步:安装
JDK
直接运行
JDK
的安装程序,选择一个安装目录,按照安装向导即可轻松完成
JDK
的安装。如需了解安装细节,请参考
Java 2 SDK
Installation Notes for Microsoft Windows
。
第三步:设置环境变量
JAVA_HOME=<JDK
安装目录
>
Path=<
原
Path>;%JAVA_HOME%/bin;%JAVA_HOME%/jre/bin
(注意其实没有等号)
本人使用的是
jdk-6-windows-i586.exe
默认安装路径
C:/Program Files/Java/jdk1.6.0
及
JAVA_HOME=C:/Program
Files/Java/jdk1.6.0
第四步:编译一个
Java
程序
请用任何文本编辑器输入以下内容并保存为
Hello.java
文件(只能保存为
Hello.java
,不能使用别的文件名),请严格注意大小写:
public class Hello
{
public static void main(String[] args)
{
System.out.println("Hello,
world.");
}
}
然后打开控制台,切换到存放
Hello.java
的目录下,输入:
javac Hello.java
如果编译通过,屏幕上没有任何显示。否则,屏幕上会输出出错信息,请仔细检查源代码。
第五步:运行一个
Java
程序
打开控制台,切换到存放
Hello.class
的目录下,然后输入:
java Hello (
注意大小写啊
!)
稍等几秒钟,屏幕输出:
Hello,
world.
说明运行成功!
如果不成功可能环境变量不正确
简单的
NDK Demo
程序
好了,环境已搭建好,现在我们开始建立一个简单的
ndk
程序来体验下整个
ndk
开发流程
:
第一步:首先我们在eclipse
中新建一个工程,工程名这里是NdkPassNormalData
。
在工程
中新建一个java
类:CallNativeDemo.java
内容如下:
package
com.jiubang.Demo.Ndk.PassNormalData;
public
class
CallNativeDemo {
static
{
System.loadLibrary
(
"NdkPassDataDemo"
);
//
注意库文件名,对于
NdkPassDataDemo
系统会在该类初始化时加载
//libNdkPassDataDemo.so
库
,
切记勿画蛇添足加上前面的
lib
与
.so
扩展名
}
public
native
int
Sum(
int
a ,
int
b); //
加上
native
表示该方法由
.so
实现
public
native
String StrCat(String str1 , String str2);
}
编写好该
java
文件后,先编译,然后用
javah
生成
ndk
中我们需要的
c
头文件
:
进入到工程的
bin
目录下输入:
javah
-jni
com.jiubang.Demo.Ndk.PassNormalData.CallNativeDemo
然后会在当前目录下生成com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo.h
文件
内容大概如下:
/* DO NOT EDIT THIS FILE - it is
machine generated */
#include <jni.h>
/* Header for class
com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo */
#ifndef
_Included_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo
#define
_Included_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:
com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo
* Method:
Sum
* Signature: (II)I
*/
JNIEXPORT jint JNICALL
Java_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo_Sum
(JNIEnv *, jobject, jint, jint);
/*
* Class:
com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo
* Method:
StrCat
* Signature:
(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
Java_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo_StrCat
(JNIEnv *, jobject, jstring, jstring);
#ifdef __cplusplus
}
#endif
#endif
第二步:在我们新的工程中加一个名为:jni
的文件夹。这个文件夹就是放原生态c/c++
的源码的地方,我们make
的时候cygwin
就是编译这个文件夹的。
第三步:在jni
文件夹里新建一个Android.mk
文件。注意,后缀为.mk ,
且文件夹一定要小写
Android.mk
的内容为:
LOCAL_PATH := $(call my-dir) <---------
默认的,不需要更改
include $(CLEAR_VARS)
<--------
默认的,不需要更改
LOCAL_MODULE := native
<--------
在java
类引用时的名称
LOCAL_SRC_FILES := myNative.c <------
在jni
文件夹下的
c/c++
的名称
include $(BUILD_SHARED_LIBRARY) <--
默认的,不需要更改
LOCAL_PATH := $(call my-dir)
<---------
返回当前路径
include $(CLEAR_VARS)
<--------
清除先前定义的环境变量
LOCAL_MODULE := NdkPassDataDemo
<--------
在
java
类引用时的名称
LOCAL_CPP_EXTENSION := cpp
LOCAL_SRC_FILES := Fun.cpp
<------
需要编译的源文件
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib –llog
<--
打
log
要用到的库,这里暂时不大明白为什么库名是这样
…
include
$(BUILD_SHARED_LIBRARY)
<--
这里指的是动态库
第四步:在jni
文件夹里新建一个
Fun.cpp
的文件。这个文件就是c/c++
文件。
Fun.cpp
的内容为:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <android/log.h>
#include "com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo.h"
//
对应
public
native
int
Sum(
int
a ,
int
b)
的实现
jint JNICALL
Java_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo_Sum(JNIEnv* aEnv,
jobject aThis, jint aParamA, jint aParamB)
{
int
sum = 0;
__android_log_print(ANDROID_LOG_INFO
, "Ndk_PassNormalData" , "CallNativeDemo_Sum Coming");
sum
= aParamA + aParamB;
FILE*
file = fopen("/sdcard/hello.txt","w+");
if
(file != NULL)
{
fputs("HELLO
WORLD!/n", file);
fflush(file);
fclose(file);
}
__android_log_print(ANDROID_LOG_INFO
, "Ndk_PassNormalData" , "CallNativeDemo_Sum Leaving");
return
sum;
}
//
对应
public
native
String
StrCat(String str1 , String str2)
实现
jstring JNICALL
Java_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo_StrCat(JNIEnv *aEnv,
jobject aThis, jstring aStr1, jstring aStr2)
{
__android_log_print(ANDROID_LOG_INFO
, "Ndk_PassNormalData" , "CallNativeDemo_StrCat Coming");
const
char* str1 = aEnv->GetStringUTFChars(aStr1 , 0);
const
char* str2 = aEnv->GetStringUTFChars(aStr2 , 0);
//char* str1 = (char*)(*aEnv)->GetStringUTFChars(aEnv
,aStr1 , 0);
//char* str2 =
(char*)(*aEnv)->GetStringUTFChars(aEnv ,aStr2 , 0);
int str1_len = strlen(str1);
int str2_len = strlen(str2);
// char* pszRet =
malloc(str1_len + str2_len + 1);
char*
pszRet = new char[str1_len + str2_len + 1];
strcpy(pszRet,
str1);
strcat(pszRet,
str2);
//jstring
jstrRet = (*aEnv)->NewStringUTF(aEnv, pszRet);
jstring jstrRet = aEnv->NewStringUTF(pszRet);
// free(pszRet);
delete pszRet;
__android_log_print(ANDROID_LOG_INFO ,
"Ndk_PassNormalData" , "CallNativeDemo_StrCat Leaving");
return jstrRet;
}
然后就可以开始编译了
:
打开
cygwin,
进入到工程的
jni
目录,然后执行 ndk-build
有看到
Install
就
OK
了
然后会发现工程目录下会多了一个
lib
与
obj
的目录
最后在
android
工程里加上调用这些
ndk
本地方法的代码:
CallNativeDemo nativeDemo = new CallNativeDemo(); int value = nativeDemo.Sum(10, 20); String str = nativeDemo.StrCat("who", "are you"); TextView v = (TextView)findViewById(R.id.textview1); v.setText(str);
运行,得到结果:
更多的
jni
数据传递处理相关资料参见:
http://andilyliao.javaeye.com/blog/494255
http://blog.csdn.net/sunyujia/archive/2008/05/03/2371557.aspx
NDK
示例开发参考:
http://blog.csdn.net/GEOLO/archive/2010/10/20/5953941.aspx
本教程工程下载:
http://download.csdn.net/source/3224679
相关文章推荐
- Windows驱动开发入门指引
- Android NDK开发轻松入门
- [译]Kinect for Windows SDK开发入门(十五):进阶指引 下
- 微信公众账号开发教程(三) 实例入门:机器人(附源码)(转)
- Android NDK开发入门-访问Java中的域
- Kinect for Windows SDK开发入门(15):进阶指引 下
- 学习Spark的入门教程——《Spark核心源码分析与开发实战》
- Android NDK开发入门(一)
- Android源码级开发-入门篇-下载源码
- Java版推箱子(搬箱子)游戏开发入门示例及源码
- C#微信开发系列笔记(1)入门指引
- windows下android ndk开发入门
- Android NDK开发(一)入门篇
- 小程序开发之基础入门指引
- C#使用Xamarin开发可移植移动应用(1.入门与Xamarin.Forms页面),附源码
- Android NDK开发轻松入门
- Android NDK开发入门步骤详解
- Android NDK开发轻松入门
- 系统开发(19):Android NDK 入门