新增LED設(shè)備--從上層到底層理解安卓架構(gòu)之Service篇
Android內(nèi)有許多系統(tǒng)管理服務(wù),如
窗口管理服務(wù)WindowManagerService
電源管理服務(wù)PowerManagerService
通知管理服務(wù)NotifacationManagerService
電池管理服務(wù)BatteryManagerService等等
這些Manager提供了很多對(duì)系統(tǒng)層的控制接口。并且他們是由SystemServer在開機(jī)后啟動(dòng)并管理的。自定義的服務(wù)加入后,也類似這些系統(tǒng)服務(wù),開機(jī)會(huì)自動(dòng)啟動(dòng),并且也有同樣的上層的訪問接口。
添加一個(gè)自定義的系統(tǒng)服務(wù),需要按照service的框架要求實(shí)現(xiàn)以下幾步:
1、TestLedService服務(wù)
路徑:frameworks/base/services/core/java/com/android/server/TestLedService.java
package com.android.server;import android.content.Context;import android.util.Slog;import android.app.ITestLedService;import android.content.BroadcastReceiver;import android.app.ActivityManager;import android.content.ComponentName;import android.content.Intent;import android.content.IntentFilter;import android.os.SystemProperties;import android.content.pm.PackageManager;import java.io.BufferedReader;import java.io.IOException;import java.io.DataOutputStream;import java.io.DataInputStream;import java.io.InputStreamReader;import java.text.SimpleDateFormat;import java.util.Date;public class TestLedService extends ITestLedService.Stub {private final Context mContext;private boolean mFlag;private boolean mled2On = false;private int mFlashDelay = 1000;public TestLedService(Context context) {super();mContext = context;testledinit_native();mFlag = true;if(mFlag){new Thread(new led2Flash()).start();}}public void SetLed1(int on){setled1_native(on);}public void SetLed2(int delay){mFlashDelay = delay;if(!mFlag && mFlashDelay != 0){new Thread(new led2Flash()).start();}if(delay == 0){mFlag = false;}}class led2Flash implements Runnable {public void run(){while(true){Slog.i("TestLed_service", "led2 flash");if(mled2On){setled2_native(0);mled2On = false;}else{setled2_native(1);mled2On = true;}try{Thread.sleep(mFlashDelay);}catch(Exception e){e.printStackTrace();}if(!mFlag){break;}}}}private static native boolean testledinit_native();private static native void setled1_native(int val);private static native void setled2_native(int val);}
TestLedService實(shí)現(xiàn)了兩個(gè)led的控制的函數(shù),SetLed1設(shè)置led1開與關(guān),setLed2設(shè)置led2的閃爍頻率。分別調(diào)用了JNI的函數(shù)setled1_native和setled2_native。
2、TestLedManager.java
路徑:frameworks/base/core/java/android/app/TestLedManager.java
package android.app;import android.app.ITestLedService;import android.util.Slog;import android.os.RemoteException;public class TestLedManager {private final ITestLedService mService;public TestLedManager(ITestLedService mService) {this.mService = mService;}public void SetLed1(int on){try {mService.SetLed1(on);} catch (RemoteException ex) {ex.printStackTrace();}}public void SetLed2(int delay){try {mService.SetLed2(delay);} catch (RemoteException ex) {ex.printStackTrace();}}}
Manager是APP和service通訊的橋梁,通過系統(tǒng)接口getSystemService,app獲取到該service的Manager。而在TestLedManager中就是將service內(nèi)實(shí)現(xiàn)的函數(shù)接口重新封裝了一下。
3、ITestLedService.aidl
路徑:frameworks/base/core/java/android/app/ITestLedService.aidl
package android.app;
// Declare any non-default types here with import statementsinterface ITestLedService {/*** Demonstrates some basic types that you can use as parameters* and return values in AIDL.*/void SetLed1(int on);void SetLed2(int delay);}
TestLedService和TestLedManager在不同的進(jìn)程,所以要考慮到進(jìn)程通訊的問題。Manager通過增加一個(gè)aidl文件來描述通訊接口。
4、aidl加入編譯mk
路徑:frameworks/base/Android.mk
LOCAL_SRC_FILES += \……\core/java/android/app/ITestLedService.aidl \
5、Context.java新增服務(wù)名
路徑:frameworks/base/core/java/android/content/Context.java
public static final String TestLed_SERVICE="TestLed";
6、注冊(cè)服務(wù)
路徑:frameworks/base/core/java/android/app/SystemServiceRegistry.java
import android.app.TestLedManager;import android.app.ITestLedService;final class SystemServiceRegistry {……static {……registerService(Context.TestLed_SERVICE, TestLedManager.class,new CachedServiceFetcher<TestLedManager>() {public TestLedManager createService(ContextImpl ctx) {IBinder b = ServiceManager.getService(Context.TestLed_SERVICE);ITestLedService service = ITestLedService.Stub.asInterface(b);return new TestLedManager(service);}});
7、啟動(dòng)服務(wù)
路徑:frameworks/base/services/java/com/android/server/SystemServer.java
private void startOtherServices() {……TestLedService TestLed = new TestLedService(context);ServiceManager.addService(Context.TestLed_SERVICE, TestLed);
8、seliunx相關(guān)
路徑:system/sepolicy/service.te
添加
type TestLed_service, system_api_service, system_server_service, service_manager_type;
路徑:system/sepolicy/service_contexts
添加
TestLed u:object_r:TestLed_service:s0
編譯過程中會(huì)報(bào)錯(cuò),You have tried to change the API from what has been previously approved.是因?yàn)樾略隽讼到y(tǒng)api函數(shù),make update -api 后再次編譯即可。
燒錄進(jìn)設(shè)備并啟動(dòng)后,adb shell service list | grep TestLed *,就可看到新增的service已經(jīng)在運(yùn)行了,就說明成功了。
掃碼關(guān)注我們
看更多嵌入式案例
喜歡本篇內(nèi)容請(qǐng)給我們點(diǎn)個(gè)再看
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!





