Android NDK 的学习之旅-----HelloWorld

1.在 ndk sample目录下创建 项目
android create project -n ndk001 -t 8 -p /Users/zhaoshun/android/android-ndk-r8/samples/ndk001 -a Test001 -k killqq.net.ndk

2.在项目的根目录下 创建jni目录
jni目录中创建 c文件 与 android.mk文件

android.mk文件如下:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := \
HelloWorld.c
include $(BUILD_SHARED_LIBRARY)


一个Android.mk file用来向编译系统描述你的源代码。具体来说:该文件是GNU Makefile的一小部分,会被编译系统解析一次或多次。你可以在每一个Android.mk file中定义一个或多个模块,你也可以在几个模块中使用同一个源代码文件。编译系统为你处理许多细节问题。

一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。

makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。makefile 文件是许多编译器--包括 Windows NT 下的编译器--维护编译信息的常用方法,只是在集成开发环境中,用户通过友好的界面修改 makefile 文件而已。

a.
LOCAL_PATH := $(call my-dir)
一个Android.mk file首先必须定义好LOCAL_PATH变量。它用于在开发树中查找源文件。在这个例子中,宏函数’my-dir’, 由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录)。

b.
include $( CLEAR_VARS)
一个Android.mk file首先必须定义好LOCAL_PATH变量。它用于在开发树中查找源文件。在这个例子中,宏函数’my-dir’, 由编译系统提供,用于返回当前路径(即包含Android.mk file文件的目录)。

c.
LOCAL_MODULE := hello
LOCAL_MODULE变量必须定义,以标识你在Android.mk文件中描述的每个模块。名称必须是唯一的,而且不包 含任何空格。注意编译系统会自动产生合适的前缀和后缀,换句话说,一个被命名为'HcSyncml'的共享库模块,将会生成'libhello.so'文件。

d.
LOCAL_C_INCLUDES := $(LOCAL_PATH)/extra_inc$(LOCAL_PATH)/main_inc
LOCAL_C_INCLUDES 中加入所需要包含的头文件路径

e.
LOCAL_SRC_FILES
LOCAL_SRC_FILES中加入源文件路径(需要编译的文件),多个文件用 ‘\’ 隔开

f.
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib –llog
表示允许打印Log

g.
include $(BUILD_SHARED_LIBRARY) 编译共享库

HelloWorld.c文件:

#include <string.h>
#include <jni.h>
jstring Java_killqq_net_ndk_Test001_getStringFromJNI( JNIEnv* env,jobject thiz )
{
//返回一个字符串给Java层
return (*env)->NewStringUTF(env, "HelloWorld from JNI !");
}


C文件中本地方法名的命名规则
如:Java_killqq_net_ndk_Test001_getStringFromJNI( JNIEnv* env,jobject thiz )
Jstring 为 返回值 ,也可以为 void , jint 等等 类型
Java_killqq_net_ndk_Test001_getStringFromJNI 为方法名,其中以下划线(_)隔开,
初始Java 为默认写法, killqq_net_ndk为包名, Test001为类名, getStringFromJNI为声明本地方法的方法名字

4.编写项目中的java文件
Android 应用层 MainActivity.java代码:

public class Test001 extends Activity {
//也就是你mk配置文件中的 LOCAL_MODULE := hello

private static final String libSoName = "hello";
private Context mContext = null;
private Button btnClick = null;
private String mStrMSG = null;

@Override

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main);
mContext = this;
btnClick = (Button) findViewById(R.id.btn_click);
btnClick.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
//调用 JNI 层实现的方法
mStrMSG = getStringFromJNI();
if(mStrMSG == null) {
mStrMSG = "调用JNI失败";
}else {
Toast.makeText(mContext, mStrMSG, 3).show();
}
}
});
}

/**
* 声明本地方法
* 该方法为native方法.由C实现
* @return JNI 给出的信息
*/
public native String getStringFromJNI();

/**
* 载入JNI生成的so库文件
*/
static {
System.loadLibrary(libSoName);
}
}


主要功能:
a) 静态载入 So 库
static {
System.loadLibrary(libSoName);
}

b) 声明本地方法
public native String getStringFromJNI();

c) 调用本地方法
String mStrMSG = getStringFromJNI();

5.开始编译
进入到项目的根目录下
执行 ndk-build命令
zhaodeiMac:ndk001 zhaoshun$ ndk-build
Compile thumb : hello <= HelloWorld.c
SharedLibrary : libhello.so
Install : libhello.so => libs/armeabi/libhello.so
编译成功

6运行效果如下图所示:

[img]http://dl.iteye.com/upload/attachment/0084/1149/54eb29f3-f59b-31ff-9a4e-6be835b9436c.png[/img]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值