2013年12月13日 星期五

從 HelloJNI 開始 Android NDK 的使用

安裝及設定工具

從某個版本開始,在 Eclipse 的 Android Development Tools (ADT) 已經包含了對 NDK 的支援。因此在安裝 Android Development Tools (ADT) 時可以一併將 NDK plugins 安裝起來。

接著,在 Eclipse 的 Preferences 裡指定 Android SDK 的路徑,並指定 Android NDK 的路徑。在這裡,我分別將 Android SDK 及 Android NDK 放置在 /opt/android/android-sdk-linux/opt/android/android-ndk-r9b 這兩個路徑。

Android 應用程式專案設定

接著,就可以開始在 Android 應用程式專案裡使用了 Android NDK 了。

舉例來說,我建立了一個名字叫「HelloJNI++」的專案,在專案上點滑鼠右鍵,選擇 Android Tools 底下的 Add Native Support 來加入 JNI 的程式碼。

加入 Native Support 時,首先要先輸入 Native Library 的名字。這裡,我使用 hellojni 作為 Native Library 的名字,於是它將會產生一個名為 libhellojni.so 的檔案。

接著,這個步驟非常重要。在專案的 Properties 裡,找到 C/C++ General 裡的 Paths and Symbols,並在 Includes 裡加入 Android NDK 的標頭檔路徑。例如,這個專案指定的 Android API 為 19 (Android 4.4),因此我加入了 /opt/android/android-ndk-r9b/platforms/android-19/arch-arm/usr/include 這個路徑。

這個步驟非常重要,不可以省略!

範例程式碼

以下就可以開始在這個專案填入程式碼了。

Android Development Tools (ADT) 的 NDK plugins 預設會依 Native Library 的名字先建立一個 .cpp 的檔案。在這篇文章裡,由於我將 Native Library 的名字取作 hellojni,因此它會建立 jni/hellojni.cpp 這個檔案。這裡我將它更名為 jni/hellojni.c,並對應修改 jni/Android.mk 的內容:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hellojni
LOCAL_SRC_FILES := hellojni.c

include $(BUILD_SHARED_LIBRARY) 

接著,修改專案的 Java 程式碼,內容如下:

package demo.example.hellojni;

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

public class HelloActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        TextView  tv = new TextView(this);
        tv.setText( stringFromJNI() );
        setContentView(tv);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.hello, menu);
        return true;
    }
    
    public native String stringFromJNI();

    static {
        System.loadLibrary("hellojni");
    }        
} 

然後,修改 jni/hello.c,將 stringFromJNI() 實作出來。

#include <jni.h>
#include <string.h>
#include <android/log.h>

jstring
Java_demo_example_hellojni_HelloActivity_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    return (*env)->NewStringUTF(env, "Hello from JNI !");
} 

最後,從 Eclipse 的 Project 下拉選單裡執行 Build Project,就完成編譯了。然後,可以將編出來的 HelloJNI++.apk 下載到模擬器或 Android 手機上執行驗證。

張貼留言