[應用程序] (應用進程)│↓ 調用簡單API
[SoundManager] │ ├─ 代理模式+門面模式(應用進程)│ ├─ 緩存數據 ←─ 裝飾器模式(應用進程)│ └─ 轉換異常 ←─ 適配器模式(應用進程)│↓ 通過Binder跨進程調用
[Binder Proxy] │ // 自動生成的Binder代理類(運行在應用進程,但處理跨進程通信)│↓ IPC(跨進程通信)
[SoundManagerService] (SystemServer進程)│ // 實際服務實現(運行在系統進程)└─ Binder Stub // 自動生成的Stub類(系統進程接收端)
以 Sound 服務為例,展示 Android 系統中添加一個系統服務的完整流程:
1. 定義 AIDL 接口
在 frameworks/base/core/java/android/media/
創建接口文件:
// ISoundManager.aidl
package android.media;/** @hide */
interface ISoundManager {void playSound(in String soundName);void setVolume(int volume);int getCurrentVolume();boolean isMuted();
}
2. 實現服務端代碼
系統服務的服務端實現(如 ActivityManagerService)通常放在 frameworks/base/services/
在frameworks/base/services/core/java/com/android/server/sound/
中實現服務:
// SoundManagerService.java
package com.android.server.sound;import android.content.Context;
import android.media.ISoundManager;public class SoundManagerService extends ISoundManager.Stub {private final Context mContext;private int mCurrentVolume = 50;private boolean mMuted = false;public SoundManagerService(Context context) {mContext = context;}@Overridepublic void playSound(String soundName) {enforceSoundPermission();// 實際播放聲音的實現}@Overridepublic void setVolume(int volume) {mCurrentVolume = Math.max(0, Math.min(100, volume));}@Overridepublic boolean isMuted() {return mMuted;}private void enforceSoundPermission() {mContext.enforceCallingPermission("android.permission.MANAGE_SOUND","Sound permission required");}
}
3. 在 SystemServer 中啟動服務
修改 frameworks/base/services/java/com/android/server/SystemServer.java
:
// 在 startOtherServices() 方法中添加
traceBeginAndSlog("StartSoundManagerService");
mSystemServiceManager.startService(SoundManagerService.class);
traceEnd();
4. 創建客戶端管理器類
面向app開發的接口在frameworks/base/core/java/
存放的是 Android 框架的公共基礎代碼,主要分為兩類:
1.面向應用開發者:提供 App 可調用的 SDK API(如 android.app、android.content)。
2.面向系統內部:實現 Android 核心機制(如 Binder、權限管理),這些對 App 透明,但支撐 App 運行。
在 frameworks/base/core/java/android/media/
中創建:
// SoundManager.java
package android.media;import android.content.Context;public class SoundManager {public static final String SERVICE = "sound";private static ISoundManager sService;private final Context mContext;public static SoundManager get(Context context) {if (sService == null) {IBinder b = ServiceManager.getService(SERVICE);sService = ISoundManager.Stub.asInterface(b);}return new SoundManager(context);}private SoundManager(Context context) {mContext = context;}public void playSound(String soundName) {try {sService.playSound(soundName);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}public int getCurrentVolume() {try {return sService.getCurrentVolume();} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}
}
5. 在 ContextImpl 中注冊服務
修改 frameworks/base/core/java/android/app/ContextImpl.java
:
// 在 static {} 塊中添加
registerService(SoundManager.SERVICE, new ServiceFetcher() {@Overridepublic Object createService(ContextImpl ctx) {return SoundManager.get(ctx);}
});
6. 添加權限聲明
在 frameworks/base/core/res/AndroidManifest.xml
中添加:
<permission android:name="android.permission.MANAGE_SOUND"android:protectionLevel="signature" />
7. 更新系統配置
在 frameworks/base/core/res/res/values/config.xml
中添加:
<bool name="config_soundServiceEnabled">true</bool>
8. 編譯和測試
編譯系統并測試新服務:
bash
make -j8
9. 應用層調用示例
應用中使用 Sound 服務:
SoundManager soundManager = (SoundManager) getSystemService(Context.SOUND_SERVICE);
soundManager.playSound("notification");
int volume = soundManager.getCurrentVolume();