android ndk c++编译简单教程

来源:互联网 发布:我的世界开挂js 编辑:程序博客网 时间:2024/05/20 16:32

1.下载ndk编译环境

googleNDK主页上下载一个合适自己系统的版本:

http://developer.android.com/tools/sdk/ndk/index.html

我这里选择的是win7 64bit版。下载android-ndk-r9-windows-x86_64.zip解压即可。

注意:解压路径中不要包含空格,否则会失败的。建议解压至D:\Android\

2.将解压的目录加入到系统环境变量中PATH

这一步是为了可以在控制台下直接使用ndk-build,较为方便。

现在打开windows powershell(cmd也可以)来试一下吧。

PS E:\> ndk-buildAndroid NDK: Could not find applicationproject directory !Android NDK: Please define theNDK_PROJECT_PATH variable to point to it.D:\Android\android-ndk-r9\build/core/build-local.mk:130:*** Android NDK: Aborting    .  Stop.

Cygwin ,去这里下载一个cygwin并安装,

3. 安装cygwin如果出现类似上面的结果,说明ndk路径已经配置好了。继续。

注意:虽然google官方教程如是说,需要cygwin,但使用最新版ndk r9,似乎这一步并不必要。有兴趣的观众可以跳过这一步试试,告知一下结果。

 

4.新建一个android工程

笔者使用intelliJ IDEA,使用eclipse的同学请采用相同命名application名为ndk2,package名为com.s1.ndk2, activity起名为MyActivity。在MyActivityjava中加入如下代码:

public class MyActivity extends Activity {      private TextView mText;    /**     * Called when the activity is first created.     */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        mText = (TextView) findViewById(R.id.textView);  // +++        String str = getMoon();    // +++        mText.setText(str);    // +++    }      // +++    public native String getMoon();    static {        System.loadLibrary("tNDK");    }}


在main.xml中增加一个TextView.

Static中的System.loadLibrary(“tNDK”)一句,是在加载该类时动态加载so库用的,tNDK是会在后面生成的Module名字,先写在这里。而nativegetMoon方法就存在在so文件中。

<TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="Hello World, MyActivity"        android:id="@+id/textView"        />


注意:工程路径请不要含有空格,否则ndk无法支持。编译工程!

5.生成.h头文件

在工程目录下,新建一个文件夹jni,会用来存放c++文件。

现在进入工程目录下,准备生成.h头文件:

PS E:\android_work\ndk2> javah -classpath .\out\production\ndk2 -bootclasspath "D:\ProgramFiles\Android\android-studio\sdk\platforms\android-11\android.jar" -d jni com.s1.ndk2.MyActivity


         -bootclasspath:启动类路径,请手动替换成自己的路径,为android sdk目录下某一个版本的android.jar,用来寻找基类,如果不加会出现错误         -classpath:类路径,刚才编译后生成的类存放的地方,也就是最后一个参数com.s1.ndk2.MyActivity所存在的地方参数说明如下:

         -d:生成头文件的目录

         com.s1.ndk2.MyActivity,这是指定要生成.h文件的java类名

如果不报错,就可以去查看一下jni目录,是否已经生成了头文件:com_s1_ndk2_MyActivity.h

如果报javah未找到,请将java安装目录/bin 加入到系统环境变量path中。

 

6.编写c++文件

进入到jni目录下,打开com_s1_ndk2_MyActivity.h,会发现已经有了一行声明,现在要为该声明进行实现。

/* * Class:     com_s1_ndk2_MyActivity * Method:    getMoon * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_s1_ndk2_MyActivity_getMoon  (JNIEnv *, jobject);


新建一个com_s1_ndk2_MyActivity.cpp的文件,然后加入如下代码:

#include "com_s1_ndk2_MyActivity.h" jstring JNICALL Java_com_s1_ndk2_MyActivity_getMoon  (JNIEnv * env, jobject obj){    return env->NewStringUTF("Hello Moon");}


 完成后准备编译。

7.编译库

jni目录下增加一个Android.mk文件,是makefile的一部分,所以GNU Make的命令都可以在这里使用。

Android.mk内容如下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := tNDKLOCAL_SRC_FILES :=LOCAL_SRC_FILES += $(notdir $(wildcard $(LOCAL_PATH)/*.cpp))include $(BUILD_SHARED_LIBRARY)


所需修改的,只是LOCAL_MODULELOCAL_SRC_FILES这两个变量,其他都是android.mk的标配,不需修改。

LOCAL_MODULE就是库名,也就是前面java文件中需要Load的库名。

完成后,在powershell中,运行ndk-build,如果不出什么意外,就应该编译成功了。如下:

PS E:\> ndk-build"Compile++ thumb : tNDK <= com_s1_ndk2_MyActivity.cppStaticLibrary  : libstdc++.aSharedLibrary  : libtNDK.soInstall        : libtNDK.so => libs/armeabi/libtNDK.so


8. 重新编译android程序

在IDEA中重新编译android程序,然后运行,就能得到如下的结果了: