Android硬件访问服务框架思想初识
?Android的硬件訪問服務(wù)提供了一個APP調(diào)用硬件實現(xiàn)的方法模型。我們從上往下來看。應(yīng)用層面對的都是一個個的服務(wù)叫service.比如電源管理服務(wù),震動服務(wù)等等。應(yīng)用層代碼首先就需要去查詢系統(tǒng)是否存在這么一個服務(wù),或者目前是不是可以被獲取的。從這個角度,我們就牽扯出來兩個問題。a:既然去系統(tǒng)里面查找這么個服務(wù),那么首先應(yīng)該又什么地方注冊加入系統(tǒng)的。b:有了這么個服務(wù),我也得創(chuàng)建一個接口函數(shù)來鏈接APP跟這個服務(wù)函數(shù)的橋梁。我們的應(yīng)用APP通過這么一個橋梁來去訪問這個服務(wù)。
我們需要懟的就是這么個服務(wù)是怎么添加到系統(tǒng)的,以及他的前世今生。這個工作是由systemserver.java文件來做的。在 startotherservices函數(shù)中我們先去new 一個服務(wù)實例對象,然后再去addservice 將這個方法注冊到系統(tǒng)的service_manager.c這就是前面我說的系統(tǒng)。那么這個服務(wù)的方法是根據(jù)誰來實例化的呢?那么肯定會有一個class類來做,也就是說我們需要創(chuàng)建這么一個類。
APP操作的根源還是在底層,現(xiàn)在我們講好了service,那么我們還需要一個地方去注冊管理底層的方法。這個仍舊是在SystemServer.java里面集中管理。這個是通過Loadlibrary函數(shù)調(diào)用JNIonload。cpp這里面并沒有直接做JNI的處理,因為安卓各個方法如果都寫在這么一個文件里面就會顯得特別亂。我們繼續(xù)通過調(diào)用下一層的JNI文件來處理。這個JNI文件是需要隨著系統(tǒng)一起編譯的。后期我們沒改一次JNI就去編譯一次Anroid系統(tǒng),太費勁了。我們就引入了Hal文件。我們的jni只需要提供標準的接口。hal文件去實現(xiàn)這些jni。而且這些hal文件不需要跟著系統(tǒng)一起編譯,我們還可以把他做成.so文件,加載到庫里。這樣同時還解決了保密問題。對吧。
說的還是挺繞的。簡而言之。我們把底層各種封裝處理,然后提供處理啊那么一個插頭(我們的service實例化后的方法就是一個插頭,里面包含了各種處理)。我們的應(yīng)用層也使用一個插頭,當這倆插頭接到了一起,就實現(xiàn)了我們的安卓硬件訪問服務(wù)。
如果某個硬件資源只能被某一個應(yīng)用使用,可以使用下面的方法訪問硬件:
JAVA APP--->JNI_OnLoad()加載C庫---->將JAVA三個地方法與C庫函數(shù)進行關(guān)聯(lián)并注冊---->調(diào)用JAVA本地Native方法就可以訪問C庫的C接口------>進而訪問硬件驅(qū)動中的open, read, write,從進訪問硬件。但是,以上場景僅限于只有一個APP使用這個硬件資源,如果有多個應(yīng)用想要使用某個硬件時,如果還按上面方法,必須會造成硬件資源的沖突,所以此時需要有一種框架來解決這個問題。解決方案就是訪問硬件資源的程序只能并且只有一個,我們稱之為System Server, 其它要訪問這個硬件資源的APP必須要給Server發(fā)請求,由Server間接的操作硬件,從而實現(xiàn)資源的訪問。這個就稱之為硬件訪問服務(wù)。
關(guān)于硬件訪問服務(wù)需要注意以下幾點:1 System Server是由JAVA編寫的,所以它要想訪問硬件,必須要加載JNI的C庫(Loadlibrary).2 C庫的JNI_Onload函數(shù)里要注冊本地方法,分別調(diào)用各個硬件的函數(shù)來注冊本地方法。比如LED,振動器,有串口。。。等等。。3 System Server:(1)對每個硬件都要添加服務(wù),add service前提需要實現(xiàn)的是:對每個硬件構(gòu)造service,使用本地Native方法(2)對于(1)添加的服務(wù)就是向service_manager.c注冊,比如serialservice, vibratorservice, ledservice等。如果JAVA應(yīng)用程序需要使用某些Service的時候,就需要通過這個Service_manager查詢及獲取相應(yīng)的Service。
4 最終APP怎么使用?(1)APP使用之前需要獲得這個服務(wù)getService(2)最后就是使用這個服務(wù)了。執(zhí)行Service的方法
以后修改硬件驅(qū)動的時候,把驅(qū)動文件放在hal里面,如hal_led.c,有幾個好處:(1)容易修改(2)很多公司不愿意開放其硬件操作,他們只提供so文件,出于保密的目的。試想一下,如果把硬件操作源代碼放到JNI文件里,如果要修改,需要編譯整個工程,此外,硬件源代碼暴露出來了,保密性不好。
分析一下:以上操作涉及到三個進程,?1 SystemServer進程:它提供的功能如下:---a: 它向service_manager.c注冊服務(wù)---b: 加載硬件Service JNI 的C庫---C: 接收其它app的硬件操作請求,訪問硬件資源
2 Service_Manager進程:負責硬件資源各種Service的注冊添加,以及接怍JAVA應(yīng)用app的各種service查詢請求及資源的獲取。
3 JAVA應(yīng)用APP進程,它其實是一個客戶端,它首先向Service_Manager查詢獲得某一個Service, 最后,把這個Service發(fā)送給SystemServer進程以請求相應(yīng)的服務(wù),
而以上三個進程之間的內(nèi)部通信,主要依靠Android內(nèi)核的Binder Driver系統(tǒng)進行內(nèi)部進程間通信。這個Binder并不是linux內(nèi)核自帶的,是google公司對linux內(nèi)核進行修改添加的一個驅(qū)動程序,可實現(xiàn)更加高效的進程間通信。
ps:注冊Server與Service的區(qū)別,可以這么理解,Server服務(wù)器提供各種服務(wù)Services.
思考:如何實現(xiàn)一個硬件訪問服務(wù)。1 編寫JNI和HAL,以led為例,先編寫com_android_server_ledservice.cpp,用于注冊JNI本地方法。再編寫hal_led.c,里面就是實現(xiàn)open,read,write等硬件訪問接口。2 修改onload.cpp,調(diào)它調(diào)用com_android_server_ledservice.cpp內(nèi)實現(xiàn)的函數(shù),3 修改system server.java,?new ledservice()add ledservice()4編寫LEDService.java提供一個類,做接口用的,他自己是不能調(diào)用本地方法的。他是通過在systemserver.java中實例化對象提供接口來實現(xiàn)功能的!!這個地方要謹記,很容易讓人混沌不清。
5 編寫ILEDService.java接口給app使用。
?
總結(jié)
以上是生活随笔為你收集整理的Android硬件访问服务框架思想初识的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 转://RMAN跨平台可传输表空间和数据
- 下一篇: [转帖]外壳命名空间扩展