2011年1月15日 星期六

Android 上自己寫 Native Funcion with Eclipse (Windows JNI NDK)

最近剛好有些需要,就稍微研究了一下這個

研究這個花了好久,把學到的東西整理一下

系統環境: Windows 7 64-bit + Eclipse SDK 3.5.1 + Android 2.2

如果是 Linux 或是 Mac,除了 Cygwin 的步驟之外,應該大同小異


Step 1:下載並安裝 Cygwin

Android NDK 的 Windows 版要在 Cygwin 上執行

Cygwin 官網:http://cygwin.com/

安裝教學:http://home.educities.edu.tw/forster/articles/cygwin.html

在 Select packages to install 時,記得要選 gcc 還有 make

忘了選可以再從 Cygwin 的安裝檔中補上


Step 2:下載並安裝 Android NDK

到官網下載 Windows 版的 NDK,這樣才可以 Compile Android 上可以用的 library

http://developer.android.com/sdk/ndk/index.html

下載完後解壓縮,假設是放在 Cygwin 的根目錄下

接著修改 .bash_profile ,在最後加上

PATH=/android-ndk-r5:${PATH}
export PATH



存檔後在 Cygwin 執行 source .bash_profile

接著執行 ndk-build --version 測試 PATH 是否設定成功


Step 3:安裝Eclipse CDT(C/C++ Development Tool)

這是為了在 Eclipse 中可以編輯C/C++的檔案

開啟 Eclipse 的 Help --> Install New Software

在 "work with" 後方的欄位中輸入 http://download.eclipse.org/tools/cdt/releases/galileo

選則下面的套件安裝:
  • Eclipse C/C++ Development Tools
  • CDT GNU Toolchain Build Support
  • CDT GNU Toolchain Debug Support
  • CDT Utilities
  • Eclipse C/C++ Development Platform
裝完之後會需要重開 Eclipse


Step 4:HelloJNI

建立一個 Android Project

整個 Project 要放在 Cygwin 的資料夾下,這樣 NDK 才抓得到

JNItestor.java

package test.jni;

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

public class JNItestor extends Activity {
TextView tv;

static {
System.loadLibrary("HelloJNI");
}
private native String hello(String what);

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView)findViewById(R.id.TextView01);
tv.setText(hello("JNITest"));
}
}


接著新增一個資料夾叫  jni

新增兩個檔案 Hello.c、Android.mk

以下為兩個檔案的內容:

Hello.c

#include <jni.h>
#include <stdlib.h>
#include <stdio.h>

JNIEXPORT jstring JNICALL Java_test_jni_JNItestor_hello(JNIEnv *env, jobject obj, jstring what) {
const jbyte *l_what;
char *result;

l_what = (*env)->GetStringUTFChars(env, what, NULL);
if (l_what == NULL) {
return NULL; /* OutOfMemoryError already thrown */
}

result = malloc(strlen(l_what) + 8);
if (result == NULL) {
return NULL;
}
sprintf(result, "Hello: %s", l_what);

return (*env)->NewStringUTF(env, result);
}

這裡說明一下:

Java_test_jni_JNItestor_hello

test_jni 對應到的是 package

JNItestor 是 Class Name

hello 是 Class 中 native function 的名字

這個 function 會把傳進來的字串加上 Hello: 之後回傳


Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES := Hello.c

LOCAL_MODULE := HelloJNI

include $(BUILD_SHARED_LIBRARY)


再來就是設定 C Compiler 的部分了

在專案名稱上按右鍵 --> Properties --> Builders --> New--> Program

Main:

Name 可以隨便打

Location 要打 Cygwin 的 bash 路徑。(ex. C:\cygwin\bin\bash.exe)

Working Directory 打 bash 所在的路徑。(ex. C:\cygwin\bin\)

Arguments 打  --login -c "cd <Project Path> && ndk-build"

<Project Path> 換成 Cygwin中的 Project 路徑 (ex. /AndroidProject/JNITest)
"<" 和 ">" 不用保留

Refresh:

Refresh resources upon completion 打勾

Build Option:

將Allocate Console打勾

將Launch in background打勾

將After "Clean"打勾

將During manual builds打勾


這樣就完成設定了,在Project Name上按右鍵 選 Build Project

看看是否可以 Build 成功,如果成功會多出一個 lib 的資料夾

裡面有 libHelloJNI.so

這時在安裝到手機上跑就可以了



參考資料:

http://abitno.me/a-simple-tutorial-to-jni

http://abitno.me/a-simple-tutorial-to-android-ndk

http://cheng-min-i-taiwan.blogspot.com/2010/06/android-ndk-hellojni.html

2 則留言:

  1. 你好,我使用eclipse 3.4.2版本,在進行安裝CDT C/C++ Development Tool時總會跳出
    Cannot complete the request. See the details.
    Unsatisfied dependency: [org.eclipse.cdt.gnu.debug.feature.group 6.0.0.201002161416]
    requiredCapability: org.eclipse.equinox.p2.iu/org.eclipse.core.variables/3.2.200
    ...
    等等的訊息,請問這該如何解決呢?

    回覆刪除
  2. 網路上也有人遇到相同的問題

    http://groups.google.com/group/eclim-user/browse_thread/thread/a2bb5f161139a3e4?pli=1

    他說 CDT 6 需要在 eclipse 3.5 以後才能執行

    所以可能要將你的 eclipse 升級了

    回覆刪除