NDK使用之HelloWorld

来源:互联网 发布:如何评价蒋方舟 知乎 编辑:程序博客网 时间:2024/04/30 10:53
NDK使用之HelloWorld

1,准备工作之环境搭建,见Android环境搭建

2,新建android项目,项目名TestHelloWorld,项目保存位置D:\Users\wanghu\workspace\helloworld,然后点击next

 

3,选择SDK版本(我这选的是4.0.3)点next

4.配置项目的包名与入口Activity如下,点finish完成创建

 

5.1)在包名"com.bravestarr.testnative"下新建"SayHello"类,如下图,然后点击finish

5.2)SayHello.java类代码如下:

package com.bravestarr.testnative;public class SayHello {    public native void say();    public native String getStringFromJNI();}

5.3)dos窗口下按如下命令操作,cd到项目的class目录D:\Users\wanghu\workspace\helloworld\bin\classes

通过javah命令针对java编译出的class文件,生成C/C++的头文件,下面javah的意思是生成SayHello.class对应的C/C++的头文件,执行javah命令后自动会在classes的目录下生成一个com_bravestarr_testnative_SayHello.h文件,该文件代码如下:

复制代码
/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_bravestarr_testnative_SayHello */#ifndef _Included_com_bravestarr_testnative_SayHello#define _Included_com_bravestarr_testnative_SayHello#ifdef __cplusplusextern "C" {#endif/* * Class:     com_bravestarr_testnative_SayHello * Method:    say * Signature: ()V */JNIEXPORT void JNICALL Java_com_bravestarr_testnative_SayHello_say  (JNIEnv *, jobject);/* * Class:     com_bravestarr_testnative_SayHello * Method:    getStringFromJNI * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_bravestarr_testnative_SayHello_getStringFromJNI  (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif
复制代码

5.4)根目录新建名为jni的文件夹,如下图,然后将5.3中生成的com_bravestarr_testnative_SayHello.h头文件剪切到jni文件夹中,并新建sayhello.c文件实现头文件中的方法

sayhello.c文件源码(C实现)如下:

sayhello.cpp文件源码(C++实现,源码同"sayhello.c")

复制代码
/* * sayhello.c * *  Created on: 2012-9-17 *      Author: wanghu */#include "com_bravestarr_testnative_SayHello.h"//若想在C/C++中使用android的Log功能,则引入"log.h"头文件#include "log.h"#include <stdio.h>JNIEXPORT void JNICALL Java_com_bravestarr_testnative_SayHello_say  (JNIEnv * env, jobject obj){    LOGI("Hello World~~~");    return;}JNIEXPORT jstring JNICALL Java_com_bravestarr_testnative_SayHello_getStringFromJNI  (JNIEnv * env, jobject obj){    LOGI("here will return a String 'Hello World'");    jstring newstring = (*env)->NewStringUTF(env,"Hello World");    const char* str= (*env)->GetStringUTFChars(env, newstring ,NULL);//使用GetStringUTFChars方法将"Hello World"转成UTF-8格式的string的对象str    (*env)->ReleaseStringUTFChars(env, newstring, str);//释放str对象的空间,如果不显示的调用的话,JVM中会一直保存该对象,不会被垃圾回收器回收,因此就会导致内存溢出    return newstring;}
复制代码

"log.h"头文件内容如下:

#include <android/log.h>#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , "bravestarr", __VA_ARGS__)#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , "bravestarr", __VA_ARGS__)#define LOGW(...) __android_log_print(ANDROID_LOG_WARN , "bravestarr", __VA_ARGS__)#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , "bravestarr", __VA_ARGS__)

5.5)jni文件夹中新建Android.mk文件,内容如下,其中注释的LOCAL_SRC_FILES := sayhello.cpp为C++的实现

复制代码
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)#LOCAL_MODULE表示生成的动态库名为sayhelloLOCAL_MODULE    := sayhello#LOCAL_SRC_FILES表示使用到的类LOCAL_SRC_FILES := sayhello.c#LOCAL_SRC_FILES := sayhello.cppLOCAL_LDLIBS    := -lm -llog -ljnigraphicsinclude $(BUILD_SHARED_LIBRARY)
复制代码

 

6.编译库文件(*.so),见以前发布的一篇文章“Android环境搭建(含NDK的配置与使用)”中的“NDK的使用”部分(注意:如果直接使用Cygwin进行编译,需要在jni目录新建一个Application.mk文件),编译成动态库*.so文件后,会自动生成一个NUL文件,可以使用Cygwin进行删除,先通过cd进入到项目目录中,然后使用rm删除文件,如下

Application.mk文件内容如下:

APP_PLATFORM := android-15

编译前:

编译后:

7.修改TestHelloWorldActivity,代码如下

复制代码
package com.bravestarr.testnative;import android.app.Activity;import android.os.Bundle;public class TestHelloWorldActivity extends Activity {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        SayHello hello = new SayHello();        hello.say();        System.out.println(hello.getStringFromJNI());    }        static{        System.loadLibrary("sayhello");    }}
复制代码

运行后效果

原创粉丝点击