2013年1月17日 星期四

[Android]Ubuntu + Android NDK 之章(完整版)(含轉貼)


2013/05/15更新:

實作篇:

限制: Android NDK只能用於android 1.5以上版本

1.新建一个Android工程,工程名为jnitest
2.右击jnitest工程-->new-->other;选择C/C++-->Convert to a C/C++ Project(Adds C/C++Nature)
3.右击jnitest工程-->properties;在左边找到C/C++ Build, 在右边的 Builder Settings 将
Build command: 添加ndk-build -j4
Build directore: ${workspace_loc:/jnitest}
4. 打开C/C++ Build找到Environment,在右边Add一变量
Variable: NDK
Value: /home//AndroidNDK
确保AndroidNDK下面有ndk-build,这个自己下载。
5 然后打开左边的C/C++ General-->Path and Symbols
进入右边的includes-->GNU C添加
${NDK}/platforms/android-9/arch-x86/usr/include
${NDK}/platforms/android-9/arch-arm/usr/include

GNU C++添加
${NDK}/sources/cxx-stl/stlport/stlport
${NDK}/platforms/android-9/arch-x86/usr/include
${NDK}/platforms/android-9/arch-arm/usr/include

6. 建立jni文件夾,並編寫.mk文件

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




===========================================================
Survey:ubuntu12.04配置Java和NDK环境
Survey2:
学习android JNI的那些事儿--------6. 在java中传入引用数据类型(对象)作为参数
探索无知世界Android Jni代码示例讲解
資訊園 - Android使用JNI實現Java與C之間傳遞資料(轉)
H's手札 -[轉]Android JNI實例
Android 開發筆記 - 使用 NDK / JNI 實作從底層呼叫上層 (C call Java)
智慧生活科技專業社群 - Java Native Interface (JNI) Android C++語言篇--以Hello-JNI為例
[java] Java Native Interface(JNI) 簡介與教學
======================================================================
觀念篇:高級應用,根據Android官網的描述,NDK 就是在Android中呼叫C程式,若有一些程式很耗資源ex.遊戲圖型OpenGL可以在Android系統下用jni串起來,或是要使用底層硬體的時候ex.driver…etc.就會用到。
修正:NDK是NDK,JNI是JNI. Android不需要JNI就可以呼叫C程式,但要用NDK來編譯C程式

1.JNI是什麼?

JNI就是Java Native Interface,即Java本地接口(和Android無關),是一個規範可讓JAVA调用C,C++,彙編等其他語言寫的函數。
但是在ubuntu環境下,動態庫一般是.so檔,所以我們需要將這些C/C++庫編譯成.so的格式才方便include。
我們要使用JNI,必須將以前寫好的C/C++函数改寫為符合JNI規範的函數,需要使用gcc/g++編譯,然後在JAVA裡面include這些編譯好的.so,並自己將java編譯處的bytecode和這些.so打包成apk。而且每次使用gdb 調試都要如此,因此NDK就應運而生.

2.NDK是什麼?

自我描述:就是Native Development Kit,一系列工具集合。
只要簡單的撰寫符合JNI規範的函數,並寫一個.mk文件,Android.mk文件是android中的makefile。
配置相關的属性就可直接編譯C/C++文件,並自動打包到apk中。

3.為何需要 android NDK ?

有了android sdk, 為何又來  android NDK(native development kid)呢 ? 許多人會搞混,  不清楚其中含意.   這裡就說說吧 !!!!!!
android SDK 是寫android APP的發展系統, sdk是以java語言為主, 被google封裝成apk的形式.
當程式設計師寫好app後, 執行的時候, 是被Dalvik虛擬機器執行, 而不是直接以機器碼的形式執行.   由dalvik虛擬機器執行最大的好處是, 底層硬體平台被dalvik隔離, app可以在任何android 裝置上執行, 而不用考慮其硬體cpu為何.    dalvik 接收app碼, 再將其轉換為底層cpu可執行的模式執行.

簡單的說, 經由dalvik虛擬機器處理的app, 其執行速度, 相較於以c 寫得程式, 會慢許多, 這在作video或audio運算時, 差異更大.  所以以java為程式語言的app, 與以c 為程式語言的驅動程式或其他app在android 系統內室一種trade-off, 都是必要元件.    所以google就提出來NDK, 讓程式設計師
可以在java內呼叫c, 來加快程式執行的速度.  當然這樣一來, 過去用c寫得程式, 也可以繼續使用.

這樣一來, 主程式架構可以用java來寫, 對於速度敏感的部份如驅動程式, 3d繪圖等等, 則用c來寫.
整個 android系統都是這樣運作的.  對內, android內部則用JNI(java native interface)表示java call  c  的結構.   android 上層用java, 底層用c , 中間用JNI串接.      對外, google提出ND發展系統, 以串接java與 c.  道理原理都一樣

=========================================================
環境建置篇:
筆者環境 ubuntu 12.04 64位元
1.下載Android NDK在網址http://developer.android.com/tools/sdk/ndk/index.html
2.下載後先在usr底下建一個ndk資料夾:sudo mkdir /usr/ndk
3.到下載NDK的目錄下 將下載下來的檔案搬移到/usr/ndk底下:sudo cp android-ndk-r8d-linux-x86.tar.bz2 /usr/ndk
4.解壓縮:sudo  tar jxvf ./android-ndk-r8d-linux-x86.tar.bz2
5.設定環境變數:

在這邊我只添加NDK而已,其他的路徑看個人版本不同會有差異
有關Jdk的環境配置 看最下面比較準

6.讓剛剛設定的環境變數生效:source /etc/environment
7.輸入命令ndk-build,出現如下結果表示成功

8.root權限打開bash文件 sudo vi ~/.bashrc

9.打開後在後面添加路徑
NDK=/usr/ndk/android-ndk-r8d (這裡最後別輸入/,因為我們配置的compile命令是$NDK/ndk-build
10.export NDK
11.保存退出後執行 source ~/.bashrc,讓配置生效,再執行命令echo $NDK
假如能正確顯示你配置的ndk文件夾路徑,就可以下一步。

12.NDKSamples資料夾底下測試compile一下
進入NDK samples/資料夾下,然後挑一個有mk配置的項目(即再進去各個smaples裡面的資料夾內),執行$NDK/ndk-build,假如編譯成功會在目錄下多出兩個子目錄libs,obj目录,若出現錯誤則看有沒有可能是權限問題。
sudo chmod 777 android-ndk-r8d    //將文件夾權限設成全開
sudo chown -R username.group /filepath  //更改文件夾所有者屬性,再試試看,如此,NDK環境設置就算是結束。

第一支Android+jni程式:hello JNI!
Windows環境底下建置Android + NDK參考:http://cheng-min-i-taiwan.blogspot.tw/2010/06/android-ndk-hellojni.html
必須裝Cygwin進而使用gcc去做編譯

我們要利用jni連結哪隻C程式就直接寫好到裡面去Build

在範例中,我們使用/usr/ndk/android-ndk-r8d/samples/hello-jni 這隻

所以我們在終端機模式切換目錄到底下,輸入sudo $NDK/ndk-build    就會build成。
接著打開Eclipse點選NewProjectAndroidAndroid Project from Existing Code→在Root Directory 點選Browse…

路徑選擇:/usr/ndk/android-ndk-r8d/samples/hello-jni/ 按下確定

勾選Projects:裡面的HelloJni Copy project into workspace勾選起來

就可以直接將專案匯入
ProjectExplorer裡面。需注意的是,要先確定這個專案有先使用(sudo 
$NDK/ndk-build)指令build起來。否則在Run專案的時候Android會跳出錯誤而結束程式。

1 則留言: