Android NDK开发入门
一.为什么要用NDK?
1.代码的保护,由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。
2.在NDK中调用第三方C/C++库,因为大部分的开源库都是用C/C++代码编写的。
3.便于移植,用C/C++写得库可以方便在其他的嵌入式平台上再次使用。
二、windows下开发环境
NDKr7开始,windows版NDK提供了ndk-build.cmd脚本,这样就可以直接用这个脚本进行编译而不需要cygwin了。
需要软件:
²TheJDK(Java Development Kit)
²TheAndroid SDK(Software Development Kit)
²TheAndroid NDK(Native Development Kit)
²AnIDE(Integrated Development Environment): Eclipse
注:从NDKr7开始不需要安装cygwin(1to 9),android ndk提供了ndk-buil.cmd脚本,这样就可以直接用这个脚本进行编译。如果快速进入开发可以从“三”开始。
1. Go to http://cygwin.com/install.html.
2.下载 setup.exe并执行
3.选择安装方式from internet
4.按照向导下一步.
5.选择下载地址.
推荐使用国内的服务器:
6.推荐安装Devel/make and Shells/bash 包:
7.按向导进行安装.
8.安装以后运行Cygwin.您的个人资料文件会在第一次启动创建.
9.输入下面的命令,测试cygwin是否正常工作:
$make –version
安装 jdk、sdk、eclipse+adt略
安装Ndk下载地址
http://developer.android.com/tools/sdk/ndk/index.html
10.现在,解压缩ndk包到固定位置(如,C:\android\android-ndk),再次避免在安装路径中留下空格(在使用make时会出现问题),为了方便执行命令,设置ndk环境变量。
11.打系统变量窗口建立环境变量ANDROID_SDKandANDROID_NDK
12.追加%ANDROID_SDK%\tools,%ANDROID_SDK%\platform-tools%ANDROID_NDK%到PATH
13.当cygwin运行时,所有的windows系统变量应该被自动导入,打开一个终端窗口检查一下NDK是否可用:
$ndk-build –-version
14.现在检查ant版本,确保在cygwin上能正常工作:
$ ant –version
第一次的Cygwin应该发出一个惊人的警告:路径是在MS-DOS风格而不是POSIX。事实上, Cygwin的路径是模拟的,应该类似于/cygdrive/<Drive letter>/<Path toyour directory with forward
slashes>.如Ant被安装在c:\ant,那么路径应该显示为/cygdrive/c/ant.
15.让我们来解决这个问题,转到您的Cygwin目录.你应该发现home/<your user name>包含a.bash_profile(注意:我安装的时候我的home文件夹下面神马都没有,解决的办法:首先打开环境变量,把里面的用户变量中的HOME变量删掉,在C:\cygwin\home文件夹下建立名为Administrator的文件夹(是用户名),然后把E:\cygwin\etc\skel\.bash_profile拷贝到该文件夹下,我的是C:\cygwin\home\User)
打开并编辑此文件。
16.在脚本的末尾,转换Windows环境变量到Cygwin的变量使用cygpath工具.PATH并不需要被转换,因为它是由Cygwin的自动处理的:
exportANT_HOME=`cygpath -u "$ANT_HOME"`
exportJAVA_HOME=`cygpath -u "$JAVA_HOME"`
exportANDROID_SDK=`cygpath -u "$ANDROID_SDK"`
exportANDROID_NDK=`cygpath -u "$ANDROID_NDK"`
转换了环境变量中定义的Windows路径到Cygwin的路径。
-u:To convert Windows paths to Unix paths
-w:To convert Unix paths to Windows paths
-p:To convert a list of paths (separated by ; on Windows and : on Unix)
17.重新打开Cygwin窗口检查Ant版本这时则不会出现warning::
$ ant –version
三、使用eclipse建立第一个android应用程序
首先到http://www.eclipse.org/cdt/downloads.php,找到对应你Eclipse版本的CDT插件的在线安装地址。Juno版本的eclipse安装地址:http://download.eclipse.org/tools/cdt/releases/juno.
建立工程MyProject如下图步骤(略)
1.打开MyActivity.java,声明一个本地方法,该方法没有方法体。
public class MyActivity extends Activity {
public native String getMyData();
...
2.然后,使用静态初始化块加载包含这个方法的本地库。在Activity实例被初始化此块将被调用:
...
static {
System.loadLibrary("mylib");
}
...
3.最后,在创建活动实例时,调用本地方法和更新屏幕内容与它的返回值:
...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setTitle(getMyData());
}
}
现在,让我们准备建立本机代码所需的项目文件.
4.在项目MyProject中建立jni目录
5.在JNI目录,创建一个名为Android.mk的新文件。如果CDT安装正确,该文件在PackageExplorer视图中具有特定的图标。
6.在这个文件写出下列内容。这说明如何编译我们的本地命名库mylib,它包含一个源文件com_myproject_MyActivity.c:
include $(CLEAR_VARS)
LOCAL_MODULE :=mylib
LOCAL_SRC_FILES :=com_myproject_MyActivity.c
include $(BUILD_SHARED_LIBRARY)
至于本地编译项目文件准备好后,我们就可以写出预期的原生源代码。尽管C实现文件必须手工编写,相应的头文件可以用JDK提供的一个辅助工具来javah来生成。
JDK:javah.
7.在eclipse中打开菜单Run | External Tools | External Tools Configurations….
8.创建具有以下参数的新程序运行配置:
Name:MyProject javah.
Location:${env_var:JAVA_HOME}\bin\javah.exe. In Mac OS X and Linux,it is usually/usr/bin/javah.
Workingdirectory:${workspace_loc:MyProject\bin\classes}.
Arguments:-d ${workspace_loc:MyProject\jni}-jni com.myproject.MyActivity
或
Name:javah
Location:${env_var:JAVA_HOME}\bin\javah.exe.
Workingdirectory:${project_loc}\src.
Arguments:-classpath${project_loc}\bin\classes –d ${project_loc}\jni –jni ${java_type_name}
9.切换到Refresh标签,checkRefresh resources uponcompletionandselectSpecific resources.使用 theSpecifyResources…按钮,选定jni文件夹.
10.最后,点击Run执行javah,一个新文件com_myproject_MyActivity.h生成在jni文件夹.
它包含了一个在java端的本地方法getMyData():
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_myproject_MyActivity */
#ifndef _Included_com_myproject_MyActivity
#define _Included_com_myproject_MyActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:com_myproject_MyActivity
* Method:getMyData
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_myproject_MyActivity_getMyData
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
11.实现com_myproject_MyActivity.c:
#include "com_myproject_MyActivity.h"
JNIEXPORT jstring Java_com_myproject_MyActivity_getMyData
(JNIEnv* pEnv, jobject pThis)
{
return (*pEnv)->NewStringUTF(pEnv,
"My native project talks C++");
}
$ cd <your project directory>/MyProject
$ ndk-build
如:
$cd/cygdrive/d/android_workspace/MyProject
$ ndk-build
Eclipse中尚未配置编译本机代码(后续章节介绍),只能编译Java代码。尝试手工编译本地代码
本地库被编译到libs/armeabi目录并命名为libmylib.so.在编译过程中生成的临时文件被保存在obj/local录.
13.从eclipse再次运行MyProject,将得到下面的结果: