1. 程式人生 > >android jni的編寫, 控制led燈

android jni的編寫, 控制led燈

         jni, java native interface, java的本地介面,如果java程式碼想去呼叫native方法(實際就是c/c++函式),就需要用jni技術,在傳統的java中jni技術就已經存在,但是由於傳統的java程式碼中,不太去寫架構或者平臺相關的程式碼,所以以前jni不是太惹人注意,直到android出現後,android本身是一個linux作業系統, linux中的應用程式設計中就使用c/c++程式碼去呼叫驅動,假如android的應用apk想去呼叫底層的裝置驅動,那麼就必須要去呼叫c/c++程式碼,所以此時jni就顯得很重要,它起著承上啟下的作用.

           jni的寫法有好幾種,在這裡先介紹在android原始碼包+linux環境下的jni程式設計方式,隨後會介紹ndk中的jni的程式設計方式

           程式設計之前首先需要給大家介紹一個大體的框架,我們需要在apk中去點一個led燈,此時就像做飯一樣,介紹幾個主料:

            1, apk,實現button點燈

             2, jni程式碼,呼叫linux的系統呼叫,去控制驅動

             3, 驅動,完成控制led硬體

首先介紹apk中使用jni中的幾個介面

介面一: 呼叫動態庫

             static{

              System.loadLibrary("led_jni"); // /system/lib/libled_jni.so

       }

介面二: 宣告本地方法

              public native int OpenDev();

              public native int DevOn();

              public native int DevOff();

              public native int CloseDev();

介面三: 直接呼叫本地方方法

           OpenDev();

apk程式碼的內容如下,非常簡單

 

jni程式碼的編寫原理: java中呼叫c程式碼的基本原理是通過檢視一個對映表來完成的,比如java中呼叫OpenDev方法時,實際是有一個c/c++函式與它一一對應,所以需要一個對映表,並且將其註冊給dvm,當dvm解析java中的native方法是,會去檢視這個對映表,並執行對應的c/c++函式,同時jni程式碼所在的檔案是需要編譯成動態庫,

jni程式碼可以寫成c檔案或者是cpp檔案,但是建議大家寫成cpp檔案,在此,以下程式碼是寫成一個檔案led_jni.cpp

1, 動態庫中的介面:

 a, 獲取dvm的環境變數物件,並測試jni的版本(1.4)           

   vm->GetEnv((void **)&env, JNI_VERSION_1_4)該方法是dvm給我們提供的方法,用於獲取環境變數物件JNIEnv* env,同時會檢測jni的版本是否是1.4, 該方法正常返回JNI_OK

    myRegisterNatives(env);該法是自己去實現的,引數就是通過vm->GetENv方法獲取的

b, myRegisterNatives(env)的實現,主要是為了完成對映表的註冊,會呼叫env->RegisterNatives()方法

 

 env->RegisterNatives(jclass clazz, const JNINativeMethod* methods,jint nMethods)

第一個引數: 將java中native修飾的方法所在的類轉換成jni的class型別(jclass)

          jclass mycls = env->FindClass("com/hq/JniLedTestActivity");

     env->FindClass中的引數是java中的native方法所在包和類的路徑,這個是必須要注意的,路徑是用Linux常用的路徑表示方式,而不是用windows,也不是用java中的點分方式,同時路徑必須要指定正確,否則會出錯

第二個引數: jni的對映表:

 

第三個引數: 對映表表的成員個數sizeof(myMethods)/sizeof(myMethods[0])

返回: JNI_OnLoad正常 返回JNI_VERSION_1_4

         錯誤返回一個負數

c,接下來就是介紹對映表的構造了:

程式碼的片段介紹完了,貼出完整程式碼

 

d,程式碼寫好了,Android.mk是為了編譯我們寫的程式碼,程式碼最終會編譯成動態庫:

 

 3,接下來就是驅動部分了,對於不同平臺,led的驅動的寫法是不一樣的,但是基本的寫法就是按照字元裝置的方式去寫,這個算是一個字元裝置驅動的簡單模板,可以參考一下看看