基於Android2.3.5系統:JNI與HAL執行個體解析[一]

來源:互聯網
上載者:User

基於Android2.3.5系統:JNI與HAL執行個體解析[一]
 

一:Android系統下JNI簡介

Android系統下的JNI的全稱是:Java Native Interface (JNI),JNI標準是java平台的一部分,它允許Java代碼和其他語言寫的代碼進行互動。JNI 是本地編程介面,它使得在 JAVA 虛擬機器 (VM) 內部啟動並執行 Java 代碼能夠與用其它程式設計語言(如 C、C++ 和組合語言)編寫的應用程式和庫進行互動操作。

二:為什麼Java要推出JNI

JNI在Android系統中有著廣泛的應用。Android系統底層都是C/C++實現的,上層提供的API都是Java的,Java通過JNI調用底層的實現。

 

Java世界虛擬機器使用Native語言編寫的,虛擬機器運行在具體的平台上,虛擬機器本身無法做到與平台無關,jni可以對java層屏蔽不同平台操作的差異,這樣就能實現java本身平台無關特性。適應已經用Native語言實現的技術。一些效率的問題需要Native語言實現。

 

在Java中使用JNI主要是為了以上幾點而實現的,在Anroid中的API多媒體介面MediaPlayer類,其實底層通過JNI調用libmedia庫。由於JNI的存在可以讓我們重用很多已經存在C/C++的庫,省去了重複開發的麻煩,並且可以利用很多開源的庫(Android庫中就有很多開源庫,比如libjpeg,libpng等等),並且讓我們開發的程式更有效率(C/C++代碼發揮硬體最佳效能)。

三:Java中JNI調用過程

在Java的世界裡,JNI對於應用本身來說,可以看做一個代理模式,對於開始者來說,需要使用C/C++來實現一個代理程式來實際操作目標原生函數,Java程式中則是JVM通過載入並調用JNI程式間接地調用目標原生函數。其調用的如下:

圖一:Android下JNI調用過程(Load DLL,DLL根據不同的環境而定)

Android系統Java下JNI程式開發的一般操作步驟如下:

編寫JAVA中的調用類;用javah產生C/C++原生函數的標頭檔;C/C++中調用需要的其他函數功能,實現原生函數;將項目依賴的所有原生庫和資源加到java項目的路徑中;產生JAVA程式;發布JAVA應用和so庫;

 

四:Android系統下JNI文法

Android系統Java下的JNI對於應用本身來說,可以看做一個代理模式,對於開始者來說,需要使用C/C++來實現一個代理程式來實際操作目標原生函數,基本的資料類型轉換,如下所示:

圖二:基礎資料型別 (Elementary Data Type)轉換表

備忘:符號屬性是指在JNI環境下

引用資料類型轉換表,如下所示:

圖三:引用資料類型轉換表

五:Java下JNI註冊函數

Java下的JNI命名規則:JNI層需要將JAVA函數名稱(包括包名)中的“.”換成“_”,用這種方式可以找到自己JNI層的路徑以及檔案。註冊Native函數有兩種方法:靜態註冊和動態註冊。靜態註冊靜態就是根據函數名來建立java和jni函數之間的關聯,而且要求jni層函數的名字必須遵循特定的格式,其缺點在於:需要編譯所有的java聲明的類;javah產生的jni層函數特別長;初次調用native函數時要根據名字搜尋對應的jni層函數來建立關聯聯絡,這樣影響效率。因此這裡只詳細的講解動態註冊的方式,Java native與JNI通過JNINativeMethod的結構來建立聯絡,其結構內容如下:

 

typedef struce {       const char* name;        //java中native函數的名字,不用攜帶包的路徑      const char*signature;    //java函數的簽名資訊,用字串表示,是參數類型和傳回值類型的組合     void *fnptr;             //JNI層對應的函數指標,注意他是void*的類型。 } JNINativeMethod; 
用一個Anroid系統下的執行個體來感性的認識和說明一下,(請到網上去下載Anroid2.3.4的OK6410的Anroid代碼,跟本文的路徑一致,因為我自己把這個Android2.3.4的OK6410移植到Android2.3.5的平台上)路徑為android2.3.5/frameworksaseservicesorlinx_pwm_jniPwmJniService.cpp,這是一個PWM控制的JNI,具體的如下所示:

 

 

圖四:JNINativeMethod方法 Android提供一個RegisterNatives(JNIEnv *env, Const char* className, Const JNINativeMethod* gMethods, int numMethods)來實現這個功能,其實還有一個在AndroidRuntime.cpp中也實現了一個RegisterNatives函數,兩者的功能是相同的,如下所示:

 

 

我們來看看PwmJniService.cpp函數中的JNI動態註冊吧,如下所示:

 

在JNI_OnLoad函數中,會去調用register_forlinx_server_PwmService()這個函數,而這個函數的定義如下所示:

一起來看看這行代碼:static const char* const kClassName =forlinx_pwm_server/server/PwmService;,就是通過kClassName找到相應的庫的,而這個PwmService就是在Android2.3.5/frameworksaseservicesorlinx_pwm_serverserverPwmService.java檔案,如下所示:

也就是說Java層通過這種手段實現了Java層去調用C/C++層的庫,這樣就將Anroid底層給封裝起來了,而在Android的JNI層會去調用Android的HAL層,而HAL層調用的就是Linux的驅動!!

六:JNI的記憶體回收
Java中建立的對象最後由記憶體回收行程來回收和釋放記憶體的,而對於JNI,直接對對象進行引用後不會增加引用計數值,當從JNI返回後在JNI引用的對象有可能被記憶體回收行程回收,而在JNI下面記錄的指標有可能是野指標,為瞭解決此類問題,JNI規範提供如下三類引用:

 

Local Refrence:本地引用,在JNI層函數中使用的非全域變數都是採用Local Refrence,它包含函數調用時傳入的jobject和在JNI層函數中建立的jobject,其最大的特點是一旦JNI層函數返回,這些jobject就可能被記憶體回收了。Global Refrence:全域引用,這類引用如果程式不主動調用銷毀介面將一直駐留在記憶體中。Weak Global Refrence:弱全域引用,在使用過程中有可能被釋放,調用JNIEnv中IsSameObject函數來判斷是否仍然存在。 七:Java下JNI函數的簽名資訊 Android系統下Jave的JNI的簽名Signature的書寫規則如下: ()中的字元表示參數,後面的則代表傳回值,如“()V”就表示void func(), “(II)V”表示void func(int, int)等。具體的每個字元對應關係如下:
如果java函數的參數是class,則以“L”開頭,以“;”結尾,中間是用“/”隔開的包及類名,對應的C函數名的參數則為jobject,一個例外是String類,其對應類為jstring。如下所示:
          Ljava/lang/String;    String     jstring          Ljava/net/Socket;     Socket     jobject
以android2.3.5/frameworksaseservicesorlinx_pwm_jniPwmJniService.cpp中的static const JNINativeMethod gMethods[]數組函數為例子,如下所示:
選取forlinx_set_freq函數來說明JNI簽名的問題,在中可以看到 { _set_freq, (I)Z, (void *)forlinx_set_freq }, 這樣的定義方式,對照上表中的簽名解析表格,我們就一目瞭然啦。forlinx_set_freq函數的定義如下所示:
可以看出來forlinx_set_freq的傳回值類型為: jboolean,而 jboolean所代表的JNI簽名為:Z,而 jint freq是forlinx_set_freq函數中需要設定的一個值,而 jint所代表的JNI的簽名為:I 因此forlinx_set_freq函數的簽名資訊為: (I)Z

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.