董偉巍
(武漢郵電科學(xué)研究院 湖北 武漢 430000)
JNI技術(shù)在網(wǎng)絡(luò)交互中的應(yīng)用
董偉巍
(武漢郵電科學(xué)研究院 湖北 武漢430000)
Android是一款運行在開放的Linux內(nèi)核之上的操作系統(tǒng),其上層應(yīng)用程序采用Java開發(fā)語言,底層核心類庫采用C/C++語言編寫,開發(fā)者能夠非常便捷的使用Android SDK調(diào)用豐富的API,實現(xiàn)各種功能。不僅如此,Android還支持跨平臺跨語言操作,通過JNI技術(shù)可以方便的調(diào)用使用其他語言編寫的程序,滿足各種不同的開發(fā)需求。
Android開發(fā);JNI技術(shù);跨平臺;NDK
在移動開發(fā)如火如荼的今天,Android作為目前市場占有率最高的智能手機操作系統(tǒng),自然是其中的佼佼者,其開發(fā)市場廣闊,勢如破竹,前景一片光明。Android系統(tǒng)架構(gòu)采用軟件疊層的方式進行系統(tǒng)構(gòu)建,從上至下依次為應(yīng)用程序?qū)印?yīng)用程序框架層、系統(tǒng)運行庫層和以及Linux內(nèi)核層[1]。這種構(gòu)架方式使得層與層之間相對獨立,當(dāng)某一層發(fā)生了變化時,其它層受到的影響相對較小。Android上層的應(yīng)用層和框架層都是使用Java語言,而系統(tǒng)運行庫層和Linux內(nèi)核層則是使用C/C++編寫的,所以上層Java要調(diào)用底層的C/C++函數(shù)庫必須通過Java的JNI技術(shù)來實現(xiàn)[2]。
JNI即Java Native Interface,通過JNI技術(shù)可以實現(xiàn)Java與其他語言(常見的有C、C++)的交互。JNI是完善Java功能的一個重要組成部分,JVM兼容了各種操作系統(tǒng)的差異性使用Java程序可以跨平臺運行,另一方面JNI提供了Java程序與操作系統(tǒng)和相關(guān)功能函數(shù)的交互接口使得Java功能更全面[3]。
JNI技術(shù)主要應(yīng)用在以下幾個方面:
1)在程序?qū)崟r性要求高或?qū)Τ绦蜻\算性能要求特別高時,可使用更底層的語言(如匯編、C和C++)來實現(xiàn)功能,然后在Java中調(diào)用;
2)在已有現(xiàn)成的用其他語言編寫的完整功能或者模塊時,使用Java直接調(diào)用;
3)在涉及Java標(biāo)準(zhǔn)平臺所不具備的依賴操作系統(tǒng)的特性時,使用JNI技術(shù)來實現(xiàn)。
圖1 JNI調(diào)用過程
JNI的調(diào)用過程可以抽象為一個代理模型來描述如圖 1所示,中間的 JNI-stub扮演著代理的角色,用來加載其他語言的動態(tài)庫,聲明Native接口方法;
為了與底層語言對接,通過 Javah生成頭文件,使用底層語言編寫頭文件中函數(shù)的代碼實體,實現(xiàn)各種所需的功能,這就是最右邊native,即被代理方的實體;
同時,聲明過的Native接口方法對其他Java類(圖1左邊部分)即客戶端開放,對于其他Java類來說JNI類可以通過簡答操作,直接使用,與調(diào)用其他Java類一樣方便。
JNI開發(fā)需要用到NDK即Native Development Kit,下載Android NDK。下載地址為:http://developer.android.com/tools/ sdk/ndk/index.html下載后解壓縮到工作目錄。由于NDK開發(fā)大都涉及到C/C++在GCC環(huán)境下編譯、運行,所以在Windows環(huán)境下,需要用Cygwin模擬Linux編譯環(huán)境[4]。
下載并安裝Cygwin,安裝好之后運行安裝目錄下的“Cygwin.bat”,第一次運行時,它會自動創(chuàng)建用戶信息,用戶信息存放在“.Cygwinhome”中。在運行“Cygwin.bat”打開的命令行窗口輸入:“cygcheck-c cygwin”命令,會打印出當(dāng)前Cygwin的版本和運行狀態(tài),如果status是ok的話,則cygwin運行正常。分別輸入:“make-v”和,“gcc-v”命令如果檢測成功,會有make和gcc相關(guān)版本信息打印出來。
完成后開始配置NDK工作的環(huán)境變量,找到cygwin的安裝目錄,找到一個home<用戶名>.bash_profile文件,打開 bash_profile文件,添加 NDK=/cygdrive/<盤符 >/<android ndk目錄>例如:
NDK=/cygdrive/e/android-ndk-r5
export NDK
然后保存,打開 cygwin,輸入cd$NDK,若輸出上面配置的 /cygdrive/e/android-ndk-r5信息,則表明環(huán)境變量設(shè)置成功了。
3.1使用JNI的原因
網(wǎng)絡(luò)交互涉及多種底層網(wǎng)絡(luò)參數(shù),硬件參數(shù)的獲取,網(wǎng)絡(luò)數(shù)據(jù)的自定義處理等。Java是高級語言,對于底層的操作效率較低,而C/C++在這些領(lǐng)域都已經(jīng)有了比較成熟的解決方案。通過JNI技術(shù)我們可以很方便的在Android程序里使用這些成熟的解決方案,讓它為我們的應(yīng)用需求進行服務(wù),
3.2Java應(yīng)用層
1)載入已經(jīng)編譯好的本地*.so庫文件
這段代碼說明程序開始運行時就會加載ANKOclient,static區(qū)聲明的代碼會先于onCreate方法執(zhí)行。如果程序中使用到多個庫,例如還有一個P2pClient庫 (完整的名字是p2pclient.so),并且P2pClient不是你應(yīng)用程序的入口,那么p2pclient庫會在第一次使用P2pClient時候加載。
2)定義各需要調(diào)用的函數(shù)(這里只列舉部分函數(shù))
從程序中可以看到在聲明這兩個方法時使有到 native關(guān)鍵字,native表明這兩個方法是本地方法,也就是說這兩個方法是通過本地代碼(C/C++)實現(xiàn)的,而在Java代碼中僅僅是聲明。用eclipse編譯該工程,會生成相應(yīng)的.class文件,必須在生成.h文件之前編譯工程,因為生成.h文件需要用到相應(yīng)的.class文件。
3.3編寫頭文件
利用Javah生成相應(yīng)的.h文件,根據(jù).h文件編寫相應(yīng)的C/C++代碼[5]。首先在工程目錄下建立一個JNI文件夾,進入此文件夾并輸入以下命令:
Javah-classpath bin-d jni libp2pclient
其中-classpath bin:表示類的路徑,-d jni:表示生成的頭文件存放的目錄,libp2pclient則是完整類名。此頭文件不需要用戶編譯,直接供其它C、C++程序引用。以下是生成的頭文件的部分內(nèi)容:
從上面的代碼中可以看到所聲明的函數(shù)名都比較長,不過它們的命名都是有規(guī)律的,完全是按照:Java_pacakege_class_mathod的形式來命名的。
3.4底層文件的編寫
編寫底層功能實現(xiàn)文件,需要導(dǎo)入剛剛生成的libp2pclient.h。
#include"libp2pclient.h"然后開始編寫函數(shù)實體,實現(xiàn)頭文件中的各個方法,完成需求的功能,以下為函數(shù)實體部分內(nèi)容:
此函數(shù)實現(xiàn)了硬件參數(shù)查詢的功能,返回值為一個結(jié)構(gòu)體,其中包括mac地址、通道數(shù)、是否支持拼接流在內(nèi)的三項內(nèi)容;
實現(xiàn)網(wǎng)絡(luò)參數(shù)獲取的功能,返回網(wǎng)絡(luò)參數(shù)。
3.5編譯生成相應(yīng)的庫
將寫好的功能文件編譯成可供Java類調(diào)用的庫文件之前,首先要編寫Android.mk文件,以下逐條介紹mk文件中各個內(nèi)容及其作用。
一個Android.mk文件首先必須定義好LOCAL_PATH變量。它用于在開發(fā)樹中查找源文件。在這個例子中,宏函數(shù)‘my-dir',由編譯系統(tǒng)提供,用于返回當(dāng)前路徑 (即包含Android.mk file文件的目錄)。
CLEAR_VARS由編譯系統(tǒng)提供, 指定讓 GNU MAKEFILE清除許多除LOCAL_PATH外的LOCAL_XXX變量 (例如 LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_ STATIC_LIBRARIES,……)。這是非常必要的,因為所有的編譯控制文件都在同一個GNU MAKE執(zhí)行環(huán)境中,所有的變量都是全局的。
編譯需要用到的所有庫文件,資源文件等等(這里只列舉部分)。
用來打印在c代碼里實現(xiàn)log打印。
編譯的目標(biāo)對象,LOCAL_MODULE變量必須定義,以標(biāo)識你在Android.mk文件中描述的每個模塊。名稱必須是唯一的,而且不包含任何空格。
編譯所包含的所有cpp文件(這里只列舉部分)。
7)include$(BUILD_SHARED_LIBRARY)
BUILD_SHARED_LIBRARY表示編譯生成共享庫,是編譯系統(tǒng)提供的變量,指向一個GNU Makefile腳本,負責(zé)收集自從上次調(diào)用 'include$(CLEAR_VARS)'以來,定義在LOCAL_XXX變量中的所有信息,并且決定編譯什么,如何正確地去完成。
完成Android.mk文件的編寫之后可以進行*.so庫文件的生成了,這里我們使用NDK所提供的ndk-build腳本生成共享庫libp2pclient.so,其中l(wèi)ibp2pclient.so會自動生成到libs/ armeabi/目錄下,這時我們之前在Java類中寫好的調(diào)用函數(shù)就可以實現(xiàn)功能了,最后在eclipse中刷新我們的工程[6],重新編譯生成apk,libp2pclient.so共享庫將一起打包在apk文件內(nèi)。
本文介紹了Android開發(fā)中JNI技術(shù)在網(wǎng)絡(luò)交互過程中的應(yīng)用,重點闡述了NDK環(huán)境的配置和JNI技術(shù)的實現(xiàn)。當(dāng)程序中用到了Java API不提供的特殊系統(tǒng)環(huán)境,而跨進程操作又不能現(xiàn)實時;當(dāng)訪問一些己有的本地庫,但又不想付出跨進程調(diào)用如效率、內(nèi)存、數(shù)據(jù)傳遞方面的代價時;當(dāng)Java程序中的一部分代碼對效率要求非常高,如算法計算、圖形渲染時,使用JNI技術(shù)將是不可避免的。
[1]劉正偉,文中領(lǐng),張海濤.云計算和云數(shù)據(jù)管理技術(shù)[J].計算機研究與發(fā)展,2012(S1):26-31.
[2]周貴芳,方貴明.基于JMF的跨平臺視頻點播系統(tǒng)的設(shè)計與實現(xiàn)[J].計算機應(yīng)用與研究,2007,24(4):230-236.
[3]Sylvain Ratabouil.Android NDK Beginner's Guide.Packt Publishing.2012.1.26.
[4]王家林,王家俊,王家虎.Android高級開發(fā)實戰(zhàn):UI、NDK與安全[M].北京:電子工業(yè)出版社,2013.
[5]蔣挺宇,王鵬,楊樹.基于中間語言的JNI泄漏檢查[J].計算機研究與發(fā)展,2013,52(4):898-906.
[6]Kaspersky.Mobile malware evolution part 5[EB/OL].2012. 02.28.
[7]劉康,王宣銀.基于單片機的以太網(wǎng)絡(luò)接入系統(tǒng)的實現(xiàn)及網(wǎng)絡(luò)性能分析[J].工業(yè)儀表與自動化裝置,2014(1):33-35.
[8]陳宏希,鄒益民.基于Java的Jess功能函數(shù)擴展方法[J].工業(yè)儀表與自動化裝置,2015(1):65-69.
Application of JNI technology in the network interaction
DONG Wei-wei
(Wuhan Research Institute of postal and Telecommunications,Wuhan 430000,China)
Android is an operating system that runs on an open Linux kernel.The upper application of Android adopts the programming language of Java,and the underlying core library of it using C/C++language.Therefore,it's very convenient for developers to call various API by Android SDK to realize all kinds of functions.Besides,Android supports cross-platform and cross-language operation as well,so you can easily call any program written in other languages by JNI technology to meet a variety of developing needs.
Android development;JNI technology;cross-platform;NDK
TN915.2
A
1674-6236(2016)06-0125-03
2015-05-18稿件編號:201505153
董偉?。?992—),女,湖北武漢人,工程師。研究方向:通信軟件。