网站翻书效果网站建设费用 会计分录
核心设计思想
插桩通过在系统关键流程中插入自定义逻辑,实现对系统行为的监控或修改,同时保持原有代码结构不变。其核心特点是:
- 无侵入性:不改动原有业务代码
- 动态替换:通过接口/抽象类实现逻辑替换
- 集中管理:统一通过XXXStub类控制实现
换一句程序员喜欢的人话:单例模式和接口解耦实现
本文是使用接口的方式进行实现
桩接口(Stub Interface):
DozePlusStub定义标准接口,提供单例模式插桩
桩实现(Stub Implementation):
DozePlusStubImpl包含实际业务逻辑
桩管理器(Stub Manager):
FadiEngineStub负责实现类的注入

1. 系统入口插桩(SystemServer)
在main中是android最早的启动入口,故非常适合插桩点注入
public static void main(String[] args) {// 在系统启动时注入自定义实现// 原理:利用Java类加载机制,在系统服务初始化前完成实现类替换com.android.server.engine.FadiEngineStub.collectInjectors();new SystemServer().run(); // 继续正常启动流程}
2. 桩管理类(FadiEngineStub)
public class FadiEngineStub {/*** 系统级桩注入入口* 作用:替换系统默认实现为自定义实现*/private static void collectInjectors() {// 创建具体实现类并注入到全局桩接口DozePlusStub.setInstance(Creator.createDozePlusImpl());}public static class Creator {/*** 工厂方法模式创建具体实现* 优势:可在此处实现条件化创建(如根据设备类型选择不同实现)*/public static DozePlusStub createDozePlusImpl() {return new DozePlusStubImpl(); // 返回带业务逻辑的实现}}}
3. 桩接口设计(DozePlusStub)
动态替换实现的核心方法setInstance
package com.android.server.power.dozeplus;public interface DozePlusStub {static DozePlusStub getInstance() {return InstanceHolder.get();}/*** 动态替换实现的核心方法*/static void setInstance(DozePlusStub instance) {InstanceHolder.set(instance);}class InstanceHolder {private static DozePlusStub sInstance = new DozePlusStub() {};private static DozePlusStub get() {return sInstance;}private static void set(DozePlusStub internal) {sInstance = internal;}}/*** 插桩方法声明* 典型应用:在系统原有逻辑中插入自定义事件处理*/default void screenOnEvent() {// 默认空实现保证系统不崩溃}}
4. 桩实现类(DozePlusStubImpl)
public class DozePlusStubImpl implements DozePlusStub {private long mLastScreenOnTime;/*** 实际业务逻辑实现* 被插入到DeviceIdleController的屏幕状态处理流程中*/@Overridepublic void screenOnEvent() {// 记录屏幕点亮时间(可用于统计亮屏时长等业务)mLastScreenOnTime = SystemClock.elapsedRealtime();// 可扩展:在此处添加通知逻辑、性能调优等}}
5. 系统原有逻辑插桩点(DeviceIdleController)
@GuardedBy("this")void updateInteractivityLocked() {boolean screenOn = mPowerManager.isInteractive();if (screenOn) {// >>>>> 插桩点开始 <<<<<// 原理:在系统原有状态判断逻辑中插入自定义回调DozePlusStub.getInstance().screenOnEvent();// >>>>> 插桩点结束 <<<<<mScreenOn = true;// ... 原有逻辑 ...}}
系统最简单的插桩就是单例模式把事件引过来,为了对于追求代码优雅和解耦的要求,也会进行通过单例模式+接口解耦+反射实现逻辑进行封装,让stub接口类和stubImpl实现类解耦。
