Ubuntu中為Android實(shí)現(xiàn)Application Frameworks層增加硬件訪問(wèn)服務(wù)
在數(shù)字科技日新月異的今天,軟件和硬件的完美結(jié)合,造就了智能移動(dòng)設(shè)備的流行。今天大家對(duì)iOS和Android系統(tǒng)的趨之若鶩,一定程度上是由于這兩個(gè)系統(tǒng)上有著豐富多彩的各種應(yīng)用軟件。因此,軟件和硬件的關(guān)系,在一定程度上可以說(shuō),硬件是為軟件服務(wù)的。硬件工程師研發(fā)出一款硬件設(shè)備,自然少了軟件工程師為其編寫(xiě)驅(qū)動(dòng)程序;而驅(qū)動(dòng)程序的最終目的,是為了使得最上層的應(yīng)用程序能夠使用這些硬件提供的服務(wù)來(lái)為用戶(hù)提供軟件功能。對(duì)Android系統(tǒng)上的應(yīng)用軟件來(lái)說(shuō),就是要在系統(tǒng)的Application Frameworks層為其提供硬件服務(wù)。在前面的幾篇文章中,我們著重介紹了Linux內(nèi)核層、硬件抽象層和運(yùn)行時(shí)庫(kù)層提供的自定義硬件服務(wù)接口,這些接口都是通過(guò)C或者C++語(yǔ)言來(lái)實(shí)現(xiàn)的。在這一篇文章中,我們將介紹如何在Android系統(tǒng)的Application Frameworks層提供Java接口的硬件服務(wù)。
一. 參照在Ubuntu Android HAL編寫(xiě)JNI方法提供JAVA訪問(wèn)硬件服務(wù)接口一文所示,為硬件抽象層模塊準(zhǔn)備好JNI方法調(diào)用層。
二. 在Android系統(tǒng)中,硬件服務(wù)一般是運(yùn)行在一個(gè)獨(dú)立的進(jìn)程中為各種應(yīng)用程序提供服務(wù)。因此,調(diào)用這些硬件服務(wù)的應(yīng)用程序與這些硬件服務(wù)之間的通信需要通過(guò)代理來(lái)進(jìn)行。為此,我們要先定義好通信接口。進(jìn)入到frameworks/base/core/java/android/os目錄,新增IHelloService.aidl接口定義文件:
USER-NAME@MACHINE-NAME:~/Android$ cd frameworks/base/core/java/android/os
USER-NAME@MACHINE-NAME:~/Android/frameworks/base/core/java/android/os$ vi IHelloService.aidl
IHelloService.aidl定義了IHelloService接口:
package android.os; interface IHelloService { void setVal(int val); int getVal(); }
IHelloService接口主要提供了設(shè)備和獲取硬件寄存器val的值的功能,分別通過(guò)setVal和getVal兩個(gè)函數(shù)來(lái)實(shí)現(xiàn)。
三.返回到frameworks/base目錄,打開(kāi)Android.mk文件,修改LOCAL_SRC_FILES變量的值,增加IHelloService.aidl源文件:
## READ ME: ########################################################
##
## When updating this list of aidl files, consider if that aidl is
## part of the SDK API. If it is, also add it to the list below that
## is preprocessed and distributed with the SDK. This list should
## not contain any aidl files for parcelables, but the one below should
## if you intend for 3rd parties to be able to send those objects
## across process boundaries.
##
## READ ME: ########################################################
LOCAL_SRC_FILES += /
....................................................................
core/java/android/os/IVibratorService.aidl /
core/java/android/os/IHelloService.aidl /
core/java/android/service/urlrenderer/IUrlRendererService.aidl /
.....................................................................
四. 編譯IHelloService.aidl接口:
USER-NAME@MACHINE-NAME:~/Android$ mmm frameworks/base
這樣,就會(huì)根據(jù)IHelloService.aidl生成相應(yīng)的IHelloService.Stub接口。
五.進(jìn)入到frameworks/base/services/java/com/android/server目錄,新增HelloService.java文件:
package com.android.server; import android.content.Context; import android.os.IHelloService; import android.util.Slog; public class HelloService extends IHelloService.Stub { private static final String TAG = "HelloService"; HelloService() { init_native(); } public void setVal(int val) { setVal_native(val); } public int getVal() { return getVal_native(); } private static native boolean init_native(); private static native void setVal_native(int val); private static native int getVal_native(); };
HelloService主要是通過(guò)調(diào)用JNI方法init_native、setVal_native和getVal_native(見(jiàn)在Ubuntu Android HAL編寫(xiě)JNI方法提供JAVA訪問(wèn)硬件服務(wù)接口一文)來(lái)提供硬件服務(wù)。
六. 修改同目錄的SystemServer.java文件,在ServerThread::run函數(shù)中增加加載HelloService的代碼:
@Override public void run() { .................................................................................... try { Slog.i(TAG, "DiskStats Service"); ServiceManager.addService("diskstats", new DiskStatsService(context)); } catch (Throwable e) { Slog.e(TAG, "Failure starting DiskStats Service", e); } try { Slog.i(TAG, "Hello Service"); ServiceManager.addService("hello", new HelloService()); } catch (Throwable e) { Slog.e(TAG, "Failure starting Hello Service", e); } ...................................................................................... }
七. 編譯HelloService和重新打包system.img:
USER-NAME@MACHINE-NAME:~/Android$ mmm frameworks/base/services/java
USER-NAME@MACHINE-NAME:~/Android$ make snod
這樣,重新打包后的system.img系統(tǒng)鏡像文件就在Application Frameworks層中包含了我們自定義的硬件服務(wù)HelloService了,并且會(huì)在系統(tǒng)啟動(dòng)的時(shí)候,自動(dòng)加載HelloService。這時(shí),應(yīng)用程序就可以通過(guò)Java接口來(lái)訪問(wèn)Hello硬件服務(wù)了。我們將在下一篇文章中描述如何編寫(xiě)一個(gè)Java應(yīng)用程序來(lái)調(diào)用這個(gè)HelloService接口來(lái)訪問(wèn)硬件,敬請(qǐng)期待。
以上就是Android Application Frameworks層增加硬件訪問(wèn)服務(wù)實(shí)現(xiàn)方法,后續(xù)繼續(xù)補(bǔ)充相關(guān)知識(shí),謝謝大家的支持!
相關(guān)文章
Android Studio卡很久(loading)的問(wèn)題解決辦法
這篇文章主要介紹了Android Studio卡很久(loading很久)的問(wèn)題的相關(guān)資料,需要的朋友可以參考下2017-05-05Android 混合動(dòng)畫(huà)詳解及實(shí)現(xiàn)代碼
這篇文章主要介紹了Android 混合動(dòng)畫(huà)詳解及實(shí)現(xiàn)代碼的相關(guān)資料,簡(jiǎn)單的一種動(dòng)畫(huà)(如旋轉(zhuǎn)、縮放、漸變、位移等)有時(shí)候并不能滿(mǎn)足我們項(xiàng)目的要求,這時(shí)候就需要運(yùn)用到混合動(dòng)畫(huà),需要的朋友可以參考下2016-11-11Android基于CountDownTimer實(shí)現(xiàn)倒計(jì)時(shí)功能
這篇文章主要介紹了Android基于CountDownTimer實(shí)現(xiàn)倒計(jì)時(shí)功能,簡(jiǎn)單分析了基于CountDownTimer類(lèi)實(shí)現(xiàn)倒計(jì)時(shí)功能的技巧,需要的朋友可以參考下2015-12-12關(guān)于Gradle下載失敗問(wèn)題的快速解決方法
這篇文章主要給大家分享了關(guān)于Gradle下載失敗問(wèn)題的快速解決方法,文中介紹了兩種解決方法,分別是使用已存在的gradle版本和手動(dòng)下載gradle,文中介紹的非常詳細(xì),需要的朋友們下面來(lái)一起看看吧。2017-05-05android Retrofit2網(wǎng)絡(luò)請(qǐng)求封裝介紹
大家好,本篇文章主要講的是android Retrofit2網(wǎng)絡(luò)請(qǐng)求封裝介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12Android TV listview及焦點(diǎn)處理
這篇文章主要介紹了Android TV listview及焦點(diǎn)處理的相關(guān)資料,需要的朋友可以參考下2017-06-06Android自定義標(biāo)尺滑動(dòng)選擇值效果
這篇文章主要為大家詳細(xì)介紹了Android自定義標(biāo)尺滑動(dòng)選擇值效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-09-09Android開(kāi)發(fā)之簡(jiǎn)單文件管理器實(shí)現(xiàn)方法
這篇文章主要介紹了Android開(kāi)發(fā)之簡(jiǎn)單文件管理器實(shí)現(xiàn)方法,簡(jiǎn)單實(shí)現(xiàn)了Android的文件目錄查看,文件重命名,打開(kāi),刪除等功能,需要的朋友可以參考下2016-01-01