新增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 statements
interface 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)系我們,謝謝!