Android NDK使用樣例

以下用helloworld來使用DNK
第一步,安裝NDK
1、首先下載NDK。
http://www.cnblogs.com/yaotong/archive/2011/01/25/1943615.html
解壓出來即可。
2、配置環境變量
I. 新建一個系統環境變量,變量名爲ANDROID_NDK_ROOT, 變量值爲你的NDK所在的路徑,比如我的就是D:\android-ndk32-r10-windows-x86\android-ndk-r10
這裏寫圖片描述
II. 在系統變量 Path 中添加%ANDROID_NDK_ROOT%\;
這裏寫圖片描述
3、 NDK 安裝驗證
完成上面的步驟之後,NDK的安裝到此就完成了,下面我們來驗證一下NDK安裝成功與否. 打開cmd.exe,在裏面輸入ndk-build -version,輸出以下內容,表示安裝成功。
這裏寫圖片描述

第二步,新建一個android工程來測試,採用最簡單的HelloWorld工程
1、新建helloworld工程,修改裏面的代碼,載入本地庫代碼修改如下

public class HelloWorldActivity extends Activity {
    //natvie必須聲明,用於生成C/C++代碼
    public native String HelloWorld();
    ……
    static{
        System.loadLibrary("HelloWorld");
    }
}

2、編譯上述修改的代碼,然後生成ndk h文件,步驟如下:
進入src目錄,使用javah -d ../jni com.test.helloworld.HelloWorldActivity 指令。
其中 -d:建立一個目錄。
其中../jni :在上級目錄的jni文件下生成頭文件。
原理:.java文件也不用編譯可以直接生成.h文件。
這裏寫圖片描述
會在E:\workspace\HelloWorld\jni的目錄下生成
com_test_helloworld_HelloWorldActivity.h

看看h都有些什麼內容

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_test_helloworld_HelloWorldActivity */
#include <android/log.h>

#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "VM JNI"
#define JNI_ERROR(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

#if 1
#define JNI_DEBUG(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#else
#define JNI_DEBUG(...)
#endif
#ifndef _Included_com_test_helloworld_HelloWorldActivity
#define _Included_com_test_helloworld_HelloWorldActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_test_helloworld_HelloWorldActivity
 * Method:    HelloWorld
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_test_helloworld_HelloWorldActivity_HelloWorld
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

Java_com_test_helloworld_HelloWorldActivity_HelloWorld是函數名稱,因爲我們在android工程中定義的native函數爲HelloWorld(),所以JNI的名稱是Java+包名+類名+函數名

3、根據生成的h文件,寫需要實現的c文件,放在同一文件目錄下

#include <string.h>
#include <jni.h>
#include "com_test_helloworld_HelloWorldActivity.h"
jstring
Java_com_test_helloworld_HelloWorldActivity_HelloWorld
  (JNIEnv* env, jobject thiz){
        JNI_DEBUG("JNI Java_com_test_helloworld_HelloWorldActivity_HelloWorld!!!");
        return (*env)->NewStringUTF(env, "123456!");
}

由上述代碼,我們可以發現,增加了在Android中的打印函數,具體定義可以查看h中的定義,注意:需要增加#include

# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := HelloWorld
LOCAL_SRC_FILES := com_test_helloworld_HelloWorldActivity.c

LOCAL_LDLIBS := -llog -lc -ldl  -lstdc++ -lm

include $(BUILD_SHARED_LIBRARY)

注意:有這樣一句LOCAL_LDLIBS := -llog -lc -ldl -lstdc++ -lm,這句話中-llog的作用就是增加打印,此處爲第二次需要注意的地方。

僅僅添加mk文件不夠,我們需要制定lib的類型。再增加一個
Application.mk

APP_ABI := armeabi

至此,lib 的工作全部完成,cmd中cd 到該目錄下
這裏寫圖片描述

第三步,寫測試code

……
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.hello_world_layout);
        Log.d("VM JNI", "on create execute"+HelloWorld());
        TextView tv = new TextView(this);
        tv.setText(HelloWorld()); // call LIB C
        setContentView(tv);
    }
……

運行,就可以打印出lib中需要顯示的字符了。注意:有的無法顯示漢字,採用英文字符測試下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章