在數字科技日新月異的今天,軟體和硬體的完美結合,造就了智能移動裝置的流行。今天大家對ios和android系統的趨之若鹜,一定程度上是由于這兩個系統上有着豐富多彩的各種應用軟體。是以,軟體和硬體的關系,在一定程度上可以說,硬體是為軟體服務的。硬體工程師研發出一款硬體裝置,自然少了軟體工程師為其編寫驅動程式;而驅動程式的最終目的,是為了使得最上層的應用程式能夠使用這些硬體提供的服務來為使用者提供軟體功能。對android系統上的應用軟體來說,就是要在系統的application frameworks層為其提供硬體服務。在前面的幾篇文章中,我們着重介紹了linux核心層、硬體抽象層和運作時庫層提供的自定義硬體服務接口,這些接口都是通過c或者c++語言來實作的。在這一篇文章中,我們将介紹如何在android系統的application
frameworks層提供java接口的硬體服務。
一. 參照在ubuntu為android硬體抽象層(hal)子產品編寫jni方法提供java通路硬體服務接口一文所示,為硬體抽象層子產品準備好jni方法調用層。
二. 在android系統中,硬體服務一般是運作在一個獨立的程序中為各種應用程式提供服務。是以,調用這些硬體服務的應用程式與這些硬體服務之間的通信需要通過代理來進行。為此,我們要先定義好通信接口。進入到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接口:
view plain
package android.os;
interface ihelloservice {
void setval(int val);
int getval();
}
ihelloservice接口主要提供了裝置和擷取硬體寄存器val的值的功能,分别通過setval和getval兩個函數來實作。
三.傳回到frameworks/base目錄,打開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
這樣,就會根據ihelloservice.aidl生成相應的ihelloservice.stub接口。
五.進入到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主要是通過調用jni方法init_native、setval_native和getval_native(見在ubuntu為android硬體抽象層(hal)子產品編寫jni方法提供java通路硬體服務接口一文)來提供硬體服務。
六. 修改同目錄的systemserver.java檔案,在serverthread::run函數中增加加載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());
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系統鏡像檔案就在application frameworks層中包含了我們自定義的硬體服務helloservice了,并且會在系統啟動的時候,自動加載helloservice。這時,應用程式就可以通過java接口來通路hello硬體服務了。我們将在下一篇文章中描述如何編寫一個java應用程式來調用這個helloservice接口來通路硬體,敬請期待。