Android NDK开发入门指引(有源码)
来源:互联网 发布:mac最新版本 编辑:程序博客网 时间:2024/06/10 10:18
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 notsupported), 这个我用的是在线安装方法(并且是全安装,非常大,很耗时)
安装好后启动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:/ProgramFiles/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 -jnicom.jiubang.Demo.Ndk.PassNormalData.CallNativeDemo
然后会在当前目录下生成com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo.h文件
内容大概如下:
/* DO NOT EDIT THIS FILE - it ismachine generated */
#include <jni.h>
/* Header for classcom_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 JNICALLJava_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 JNICALLJava_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 JNICALLJava_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo_Sum(JNIEnv* aEnv,jobject aThis, jint aParamA, jint aParamB)
{
intsum = 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("HELLOWORLD!/n", file);
fflush(file);
fclose(file);
}
__android_log_print(ANDROID_LOG_INFO, "Ndk_PassNormalData" , "CallNativeDemo_Sum Leaving");
returnsum;
}
// 对应public native StringStrCat(String str1 , String str2)实现
jstring JNICALLJava_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");
constchar* str1 = aEnv->GetStringUTFChars(aStr1 , 0);
constchar* 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);
//jstringjstrRet = (*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本地方法的代码:
运行,得到结果:
更多的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
- Android NDK开发入门指引(有源码)
- Android ndk开发入门
- Android NDK开发入门
- Android -- NDK开发入门
- Android NDK开发入门
- Android NDK开发入门
- Android NDK开发入门
- Android NDK开发入门
- Android NDK开发入门
- Android NDK开发入门实例
- Android NDK开发入门实例
- Android NDK开发轻松入门
- Android NDK开发轻松入门
- Android NDK开发入门实例
- Android NDK开发轻松入门
- Android NDK开发轻松入门
- Android NDK开发轻松入门
- Android NDK开发轻松入门
- 程序人生之七:我的 2010
- Ext3.3在Ie8中报错ext-all.js对象不支持此属性和方法
- php环境打开Cookie
- PMP学习中的收获
- Java中值得注意的细节1
- Android NDK开发入门指引(有源码)
- MyEclipse for Spring 8.6: Spring MVC Scaffolding
- VBS学习笔记(2): Call造成的麻烦
- java String与Date类型之间的相互转换
- 设计模式实现(五): Prototype Pattern
- java五种拼接字符串的方法
- 又在开始学习一些linux
- 设计模式实现(六): Adapter Pattern
- 使用GPIO口模拟I2C总线并挂载设备