1. 项目背景与需求分析
在Android系统开发中,系统服务(System Service)是框架层最核心的组件之一。随着Android 13的发布,开发者经常需要为特定硬件或业务逻辑添加自定义系统服务。计数器功能作为基础组件,在多种场景下都有应用需求:
- 设备性能监控(如CPU负载统计)
- 业务逻辑计数(如消息推送次数记录)
- 硬件事件统计(如传感器触发次数)
传统实现方式是在应用层通过SharedPreferences或数据库维护计数,但存在以下问题:
- 多进程访问时并发控制复杂
- 进程被杀后计数可能丢失
- 无法被系统其他服务直接调用
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统服务开发基础架构
2.1 AIDL接口定义
在frameworks/base/core/java/android/os下创建ICounterService.aidl:
aidl复制package android.os;
interface ICounterService {
void setCounterValue(String key, int value);
int getCounterValue(String key);
int increment(String key);
int decrement(String key);
}
编译后会自动生成:
- ICounterService.java(接口定义)
- ICounterService.Stub(服务端基类)
- ICounterService.Proxy(客户端代理)
2.2 服务实现类
在frameworks/base/services/core/java/com/android/server创建CounterService.java:
java复制public class CounterService extends ICounterService.Stub {
private final ConcurrentHashMap<String, AtomicInteger> counters =
new ConcurrentHashMap<>();
@Override
public void setCounterValue(String key, int value) {
counters.putIfAbsent(key, new AtomicInteger(value));
}
@Override
public int getCounterValue(String key) {
return counters.getOrDefault(key, new AtomicInteger(0)).get();
}
@Override
public int increment(String key) {
return counters.computeIfAbsent(
key, k -> new AtomicInteger(0)).incrementAndGet();
}
// 其他接口实现...
}
3. 系统服务注册流程
3.1 SystemServer注册
修改frameworks/base/services/java/com/android/server/SystemServer.java:
java复制private void startOtherServices() {
// 在系统服务启动阶段添加
try {
mSystemServiceManager.startService(CounterService.class);
} catch (Throwable e) {
Slog.e(TAG, "Failed to start CounterService", e);
}
}
3.2 ServiceManager注册
在frameworks/base/services/core/java/com/android/server/SystemServiceManager.java中添加:
java复制public <T extends SystemService> T startService(Class<T> serviceClass) {
// 已有代码...
if (serviceClass == CounterService.class) {
service = new CounterService(mContext);
}
// 注册到ServiceManager
ServiceManager.addService("counter", service);
}
4. SELinux策略配置
4.1 服务域定义
在system/sepolicy/private/service_contexts添加:
code复制counter u:object_r:counter_service:s0
4.2 策略文件
创建system/sepolicy/private/counter_service.te:
sepolicy复制type counter_service, system_api_service, system_server_service, service_manager_type;
# 允许系统服务访问
allow system_server counter_service:service_manager find;
allow system_server counter_service:service_manager add;
# 允许客户端访问
allow untrusted_app counter_service:service_manager find;
5. 客户端调用示例
5.1 获取服务代理
java复制public class CounterManager {
private static ICounterService sService;
public static ICounterService getService() {
if (sService == null) {
sService = ICounterService.Stub.asInterface(
ServiceManager.getService("counter"));
}
return sService;
}
}
5.2 实际调用
java复制try {
CounterManager.getService().increment("boot_count");
int count = CounterManager.getService().getCounterValue("boot_count");
Log.d(TAG, "Current boot count: " + count);
} catch (RemoteException e) {
Log.e(TAG, "CounterService error", e);
}
6. 性能优化与线程安全
6.1 并发控制方案
采用ConcurrentHashMap + AtomicInteger组合:
- 读操作完全无锁(get操作)
- 写操作分段锁(put操作)
- 计数操作CAS(increment/decrement)
6.2 内存优化策略
对于高频访问的计数器:
java复制@GuardedBy("this")
private final LruCache<String, AtomicInteger> hotCounters =
new LruCache(20);
public int getCounterValue(String key) {
AtomicInteger counter = hotCounters.get(key);
if (counter == null) {
synchronized (this) {
counter = counters.get(key);
if (counter != null) {
hotCounters.put(key, counter);
}
}
}
return counter != null ? counter.get() : 0;
}
7. 调试与问题排查
7.1 常见问题
-
服务未注册:
- 检查
dumpsys activity services | grep counter - 确认SystemServer日志中无启动异常
- 检查
-
SELinux拒绝:
bash复制
adb shell dmesg | grep avc根据拒绝日志补充策略规则
-
跨进程调用超时:
java复制// 在客户端设置超时 Bundle options = new Bundle(); options.putBinder(EXTRA_BINDER, new Binder()); ServiceManager.addService("counter", service, options);
7.2 性能测试方法
使用benchmark模块测试:
java复制@RunWith(AndroidJUnit4.class)
public class CounterBenchmark {
@Test
public void testIncrement() {
final ICounterService service = CounterManager.getService();
BenchmarkState state = new BenchmarkState();
while (state.keepRunning()) {
service.increment("benchmark");
}
}
}
8. 进阶功能扩展
8.1 持久化存储
修改CounterService添加:
java复制private void loadCounters() {
File file = new File("/data/system/counters.xml");
try (FileInputStream fis = new FileInputStream(file)) {
// 从XML加载计数状态
} catch (IOException e) {
Slog.w(TAG, "Failed to load counters", e);
}
}
private void saveCounters() {
File file = new File("/data/system/counters.xml");
try (FileOutputStream fos = new FileOutputStream(file)) {
// 保存到XML
} catch (IOException e) {
Slog.w(TAG, "Failed to save counters", e);
}
}
8.2 观察者模式
扩展AIDL接口:
aidl复制interface ICounterListener {
void onCounterChanged(String key, int value);
}
interface ICounterService {
void registerListener(ICounterListener listener);
void unregisterListener(ICounterListener listener);
}
实现使用RemoteCallbackList管理监听器:
java复制private final RemoteCallbackList<ICounterListener> listeners =
new RemoteCallbackList<>();
private void notifyListeners(String key, int value) {
int count = listeners.beginBroadcast();
for (int i = 0; i < count; i++) {
try {
listeners.getBroadcastItem(i).onCounterChanged(key, value);
} catch (RemoteException e) {
// 忽略已死进程
}
}
listeners.finishBroadcast();
}
9. 兼容性处理
9.1 版本适配
在ServiceManager添加版本检查:
java复制public static ICounterService getCounterService() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
return new LegacyCounterWrapper();
}
return ICounterService.Stub.asInterface(
ServiceManager.getService("counter"));
}
9.2 备用实现
对于不支持新服务的设备:
java复制private static class LegacyCounterWrapper extends ICounterService.Stub {
private final SharedPreferences prefs;
LegacyCounterWrapper() {
prefs = AppGlobals.getInitialApplication()
.getSharedPreferences("counter", Context.MODE_PRIVATE);
}
@Override
public int getCounterValue(String key) {
return prefs.getInt(key, 0);
}
@Override
public void setCounterValue(String key, int value) {
prefs.edit().putInt(key, value).apply();
}
}
10. 实际应用案例
10.1 开机次数统计
在BootReceiver中:
java复制public void onReceive(Context context, Intent intent) {
CounterManager.getService().increment("boot_count");
}
10.2 应用安装统计
在PackageManagerService中:
java复制private void scanPackageLI(File scanFile, int parseFlags) {
// 原有逻辑...
CounterManager.getService().increment("apk_installs");
}
10.3 性能监控
结合ActivityManagerService:
java复制void updateOomAdjLocked(ProcessRecord app) {
// 原有逻辑...
if (app.curAdj >= ProcessList.FOREGROUND_APP_ADJ) {
CounterManager.getService().increment("foreground_oom_adj");
}
}
