天天看點

Android NDK 環境搭建以及第一個Demo

 谷歌改良了ndk的開發流程,對于Windows環境下NDK的開發,如果使用的NDK是r7之前的版本,必須要安裝Cygwin才能使用NDK。而在NDKr7開始,Google的Windows版的NDK提供了一個ndk-build.cmd的腳本,這樣,就可以直接利用這個腳本編譯,而不需要使用Cygwin了。隻需要為Eclipse Android工程添加一個Builders,而為Eclipse配置的builder,其實就是在執行Cygwin,然後傳遞ndk-build作為參數,這樣就能讓Eclipse自動編譯NDK了。那麼我們現在開始吧:

一、關于NDK的一點解釋:                                                                                             

NDK全稱:Native Development Kit。 

NDK提供了一系列的工具,幫助開發者快速開發C(或C++)的動态庫,并能自動将so和java應用一起打包成apk。這些工具對開發者的幫助是巨大的。 

NDK內建了交叉編譯器,并提供了相應的mk檔案隔離CPU、平台、ABI等差異,開發人員隻需要簡單修改mk檔案(指出“哪些檔案需要編譯”、“編譯特性要求”等),就可以建立出so。

NDK可以自動地将so和Java應用一起打包,極大地減輕了開發人員的打包工作。

二、NDK壞境搭建:                                                                                                   

  注意事項:目前已經出了NDK-r9b了,由于作者寫這篇日志的時候 當時下載下傳的還是NDK-r8c,是以仍以NDK-r8c為例來講解。

操作類似,從ndk-7後,谷歌已經改良了ndk的操作,不需用使用cygwin來交叉編譯了,這大大的提高了我們的開發速度。

(1)下載下傳安裝NDK-r8c。

下載下傳位址:http://developer.android.com/sdk/ndk/index.html

(2)打開Eclipse,建立一個Android工程(我的取名為TestNdk),在工程目錄TestNdk下建立jni檔案夾,該檔案夾就用來儲存NDK需要編譯的檔案代碼等。

(3)開始建立并配置一個Builder

(a)Project->Properties->Builders->New,建立一個Builder。 

(b)在彈出的【Choose configuration type】對話框,選擇【Program】,點選【OK】: 

(c)在彈出的【Edit Configuration】對話框中,配置頁籤【Main】。 

在“Name“中輸入新builders的名稱(這個名字可以任意取)。

在“Location”中輸入nkd-build.cmd的路徑(這個是下載下傳完ndk8後解壓後的路徑,這個建議放在根目錄下面,路徑不能有空格和中文)。根據各自的ndk路徑設定,也可以點選“Browser File System…”來選取這個路徑。 

在“Working Diretcoty”中輸入TestNdk位置(也可以點選“Browse Workspace”來選取TestNdk目錄)。如圖1

Android NDK 環境搭建以及第一個Demo

圖1

(d)繼續在這個【Edit Configuration】對話框中,配置頁籤【Refresh】。如圖2 

勾選“Refresh resources upon completion”, 

勾選“The entire workspace”, 

勾選“Recuresively include sub-folders”。

Android NDK 環境搭建以及第一個Demo

圖2

(e)繼續在【Edit Configuration】對話框中,配置頁籤【Build options】。 

勾選“After a “Clean””,(勾選這個操作後,如果你想編譯ndk的時候,隻需要clean一下項目 就開始交叉編譯) 

勾選“During manual builds”, 

勾選“During auto builds”, 

勾選“Specify working set of relevant resources”。如圖3

Android NDK 環境搭建以及第一個Demo

圖3

點選“Specify Resources…”勾選TestNdk工程中建立的“jni“目錄,點選”finish“。 點選“OK“,完成配置。 如圖4

Android NDK 環境搭建以及第一個Demo
Android NDK 環境搭建以及第一個Demo

圖4

到此,恭喜你,編譯環境以及成功搭建完畢!

那麼搭建完了,當然要玩一玩了,好了,下面我們來跑一個demo測試一把,讓你了解一下ndk的開發流程

三、NDK程式demo的開發(下面是重點,請仔細檢視)                                                  

   1.在TestNdk工程中建立一個JniClient.class(為了調用C/C++代碼),其内容如下:

package com.ndk.test;

public class JniClient {
    static public native String AddStr(String strA, String strB);
    static public native int AddInt(int a, int b);
}      

2.生成 .h 的c++頭檔案

(1)用cmd指令定位到JniClient.class 所在目錄,輸入“javac JniClient.java“後回車,生成JniClinet.class檔案(如果是用的Eclipse建的工程,在TestNdk\bin\classes\com\ndk\test目錄下就已經有JniClinet.class檔案了)。

(2)将JniClinet.class拷貝到TestNdk\bin\classes\com\ndk\test目錄,将cmd指令定位到TestNdk\bin\classes目錄,輸入”javah com.ndk.test.JniClient“後回車,在TestNdk\bin\classes目錄下就生成了C++頭檔案com_ndk_test_JniClient.h

com_ndk_test_JniClient.h的檔案内容如下:

Android NDK 環境搭建以及第一個Demo
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_ndk_test_JniClient */

#ifndef _Included_com_ndk_test_JniClient
#define _Included_com_ndk_test_JniClient
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_ndk_test_JniClient
 * Method:    AddStr
 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_ndk_test_JniClient_AddStr
  (JNIEnv *, jclass, jstring, jstring);

/*
 * Class:     com_ndk_test_JniClient
 * Method:    AddInt
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_ndk_test_JniClient_AddInt
  (JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif      
Android NDK 環境搭建以及第一個Demo

3.在jni目錄下建立一個Android.mk檔案,其内容如下(關于mk檔案需要注意,很重要,還有c和c++檔案的mk檔案還不一樣,此處是調用c語言的mk檔案,至于其他的怎麼調用,這個自己去百度吧,在此就不多說了)

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := TestNdk
LOCAL_SRC_FILES := com_ndk_test_JniClient.c
include $(BUILD_SHARED_LIBRARY)      

4. 将剛剛手動生成的com_ndk_test_JniClient.h拷貝到TestNdk工程的jni目錄下,

然後建立一個com_ndk_test_JniClient.c檔案完成頭檔案中函數的實作,其内容如下(本來想寫兩個方法的,現在隻講解第一個方法,傳回一個字元串“HelloWorld from JNI ”,另一個方法是一個a+b的運算,方法寫到這裡,感興趣的可以自己去研究):

com_ndk_test_JniClient.c

Android NDK 環境搭建以及第一個Demo
#include "com_ndk_test_JniClient.h"
#include <stdlib.h>
#include <stdio.h>

#ifdef __cplusplus   
extern "C"  
{   
#endif  
/*
 * Class:     com_ndk_test_JniClient
 * Method:    AddStr
 * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_ndk_test_JniClient_AddStr
  (JNIEnv *env, jclass arg, jstring instringA, jstring instringB)
{
    jstring str = (*env)->NewStringUTF(env, "HelloWorld from JNI !");
    return str;       
}

/*
* Class:     com_ndk_test_JniClient
* Method:    AddInt
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_ndk_test_JniClient_AddInt
  (JNIEnv *env, jclass arg, jint a, jint b)
{
    return a + b;
}

#ifdef __cplusplus   
}   
#endif      
Android NDK 環境搭建以及第一個Demo

此刻,當編輯com_ndk_test_JniClient.c并儲存後,project下的—clean  一下工程,就可以看到TestNkd工程下的obj/local/armeabi目錄下将自動生成libTestNdk.so庫。

5.在TestNdkActivity.java中完成對JniClient.java中函數的調用(首先靜态加載動态連結so庫):

Android NDK 環境搭建以及第一個Demo
package com.ndk.test;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class TestNdkActivity extends Activity {
    static {
        System.loadLibrary("TestNdk");
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.main);
        
        //第一個方法傳入的兩個參數沒有做操作,直接傳回hello jni,不用管
        String str = JniClient.AddStr("test", "test");
        
        //第二個方法暫時不實作
        //  int iSum = JniClient.AddInt(5, 2);        
       // String strSum = "5 + 7 = " + iSum;
        
        TextView tv1 = new TextView(this);
        tv1.setText(str);
        setContentView(tv1);
    }
}      
Android NDK 環境搭建以及第一個Demo

6.運作TestNdk工程,在控制台中可以看到界面輸出來自com_ndk_test_JniClient.c 檔案中的“HelloWorld from JNI ! "了。

NDK執行個體到此完成。

後續更複雜的操作就需要深入的學習NDK/JNI了,

比如C/C++與Java的資料類型轉換,以及Android.mk檔案的編寫格式等。

如果有什麼問題,歡迎溝通交流!非常感謝您對andye的關注!關于.h檔案怎麼生成,可以看我另一篇日志,雖然是用cygwin寫的,有點舊,但是裡面有關于怎麼生成.h的截圖,供參考,位址為:http://www.cnblogs.com/yejiurui/archive/2012/11/21/2780940.html

近期有朋友需求,忘記上傳一份demo了,那麼我重新整理了一份demo,各位朋友可以下載下傳學習:

百度網盤下載下傳位址:http://pan.baidu.com/s/1gdIeUvL

demo圖檔如下:

Android NDK 環境搭建以及第一個Demo

轉載自:http://www.cnblogs.com/yejiurui/p/3476565.html