這篇博客主要針對Android NDK開發做入門級論述,所觸及到的主要有以下幾點:
1.Android NDK開發簡介
Android NDK 是在SDK前面又加上了“原生”2字,即Native Development Kit,因此又被Google稱為“NDK”。盡人皆知,Android程序運行在Dalvik虛擬機中,NDK允許用戶使用類似C / C++之類的原生代碼語言履行部份程序。NDK包括了:
2.JNI簡介
JNI是Java Native Interface的縮寫,它提供了若干的API實現了Java和其他語言的通訊(主要是C&C++)。從Java1.1開始,JNI標準成為java平臺的1部份,它允許Java代碼和其他語言寫的代碼進行交互。JNI1開始是為了本地已編譯語言,特別是C和C++而設計的,但是它其實不妨礙你使用其他編程語言,只要調用約定受支持就能夠了。使用java與本地已編譯的代碼交互,通常會喪失平臺可移植性。但是,有些情況下這樣做是可以接受的,乃至是必須的。例如,使用1些舊的庫,與硬件、操作系統進行交互,或為了提高程序的性能。JNI標準最少要保證本地代碼能工作在任何Java 虛擬機環境下。更多相干細節參見百度百科
3.工具介紹
4.構建HelloJNI項目
等不到我開發環境構建的兄弟們可以先根據其他博客自己搭建環境,相對而言環境相干的教程是比較多的,本篇博客的主要目的在于引導大家在最新環境上入手JNI開發:
第1步: 新建Android項目
新建的Android項目路徑以下圖所示:
第2步:
添加JNI文件莢
右鍵->new->Folder->JNI Folder,添加后文件目錄如圖所示:
第3步:
在jni文件夾上右鍵new ->file,命名為Android.mk,同上再新建1個hello-jni.cpp文件。Android.mk文件內容以下:
#1個Android.mk 文件首先必須定義好LOCAL_PATH變量。它用于在開發樹中查找源文件。在這個例子中,宏函數’my-dir’, 由編譯系統提供,用于返回當前路徑(即包括Android.mk file文件的目錄) #CLEAR_VARS由編譯系統提供,指定讓GNU MAKEFILE為你清除許多LOCAL_XXX變量(例如 LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 等等...), #除LOCAL_PATH 。這是必要的,由于所有的編譯控制文件都在同1個GNU MAKE履行環境中,所有的變量都是全局的。 #編譯的目標對象,LOCAL_MODULE變量必須定義,以標識你在Android.mk文件中描寫的每一個模塊。名稱必須是唯1的,而且不包括任何空格。 #編譯系統會自動產生適合的前綴和后綴,換句話說,1個被命名為hello-jni的同享庫模塊,將會生成libhello-jni.so文件。 #如果你把庫命名為‘libhello-jni’,編譯系統將不會添加任何的lib前綴,也會生成 libhello-jni.so,這是為了支持來源于Android平臺的源代碼的Android.mk文件,如果你確切需要這么做的話。 #LOCAL_SRC_FILES變量必須包括將要編譯打包進模塊中的C或C++源代碼文件。注意,你不用在這里列出頭文件和包括文件,由于編譯系統將會自動為你找出依賴型的文件;僅僅列出直接傳遞給編譯器的源代碼文件就好。 #默許的C++源碼文件的擴大名是’.cpp’. 指定1個不同的擴大名也是可能的,只要定義LOCAL_DEFAULT_CPP_EXTENSION變量,不要忘記開始的小圓點(也就是’.cxx’,而不是’cxx’) #BUILD_SHARED_LIBRARY表示編譯生成同享庫,是編譯系統提供的變量,指向1個GNU Makefile腳本,負責搜集自從上次調用include $(CLEAR_VARS)以來,定義在LOCAL_XXX變量中的所有信息,并且決定編譯甚么,如何正確地去做。還有 BUILD_STATIC_LIBRARY變量表示生成靜態庫:lib$(LOCAL_MODULE).a, BUILD_EXECUTABLE 表示生成可履行文件。 # LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello-jni LOCAL_SRC_FILES := hello-jni.cpp include $(BUILD_SHARED_LIBRARY)
hello-jni.cpp文件內容以下所示:
#include
完成后,項目目錄以下:
接著打開MainActivity.java文件,修改其內容以下:
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.TextView; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setText(NDKTestFromJNI()); setContentView(tv); } public native String NDKTestFromJNI();// native聲明,表示這個方法來自Native層。實現進程已在native層實現了 static { System.loadLibrary("hello-jni");// 加載庫,前面的lib和后綴名不用寫 } }
第4步: 打開terminal,順次按圖中輸入命令操作
此時,我們就能夠看到生成的.so文件了哈,以下圖所示:
第5步: 履行項目,運行在真機上,界面上會顯示