Android 状态机 StateMachine 详解

QuibblerAgentQuibblerAgent 2026-06-08 约 20 分钟 279 次阅读

Android 状态机 StateMachine 详解

1、StateMachine 概述

StateMachine 是 Android 框架提供的状态机实现,位于 com.android.internal.util 包中。它基于消息驱动,通过状态模式管理复杂的状态转换逻辑,广泛应用于 Android 系统内部,如 Wifi 状态管理、蓝牙连接管理等。

核心特性:

        - 基于消息驱动的状态转换

        - 支持状态层级结构

        - 提供状态进入、退出、消息处理回调

        - 支持延迟消息和定时消息

        - 线程安全,支持异步操作

应用场景:

        - 网络连接状态管理

        - 播放器状态控制

        - 业务流程状态管理

        - 复杂交互逻辑处理

        - 协议解析和状态跟踪

2、核心概念

2.1、State 类

State 是状态机中的基本单元,表示一个具体的状态:

        主要方法:

        - enter():进入状态时调用

        - exit():退出状态时调用

        - processMessage(Message msg):处理消息,返回 true 表示已处理

        - getName():获取状态名称

2.2、StateMachine 类

StateMachine 是状态机的核心类,负责管理状态和消息:

主要方法:

        - addState(State state):添加状态

        - addState(State state, State parent):添加层级状态

        - setInitialState(State state):设置初始状态

        - start():启动状态机

        - sendMessage(Message msg):发送消息

        - transitionTo(State state):切换状态

        - quit():退出状态机

2.3、状态层级

StateMachine 支持状态层级结构,子状态可以继承父状态的消息处理逻辑:

        - 父状态可以处理子状态未处理的消息

        - 状态切换时,会自动调用 enter() 和 exit()

        - 支持多层嵌套的状态结构

3、基本使用方法

3.1、定义状态类

class IdleState extends State {
    @Override
    public void enter() {
        Log.d("StateMachine", "进入空闲状态");
    }
    
    @Override
    public void exit() {
        Log.d("StateMachine", "退出空闲状态");
    }
    
    @Override
    public boolean processMessage(Message msg) {
        switch (msg.what) {
            case MSG_START:
                // 切换到工作状态
                transitionTo(mWorkingState);
                return true;
        }
        return false; // 未处理,交给父状态
    }
}
class WorkingState extends State {
    @Override
    public void enter() {
        Log.d("StateMachine", "进入工作状态");
        startWork();
    }
    
    @Override
    public void exit() {
        Log.d("StateMachine", "退出工作状态");
        stopWork();
    }
    
    @Override
    public boolean processMessage(Message msg) {
        switch (msg.what) {
            case MSG_STOP:
                transitionTo(mIdleState);
                return true;
            case MSG_PAUSE:
                transitionTo(mPausedState);
                return true;
        }
        return false;
    }
}

3.2、创建状态机

class MyStateMachine extends StateMachine {
    private static final int MSG_START = 1;
    private static final int MSG_STOP = 2;
    private static final int MSG_PAUSE = 3;
    
    private IdleState mIdleState = new IdleState();
    private WorkingState mWorkingState = new WorkingState();
    private PausedState mPausedState = new PausedState();
    
    public MyStateMachine(String name) {
        super(name);
        
        // 添加状态
        addState(mIdleState);
        addState(mWorkingState);
        addState(mPausedState);
        
        // 设置初始状态
        setInitialState(mIdleState);
    }
    
    public void start() {
        start();
    }
    
    public void sendMessage(int what) {
        sendMessage(obtainMessage(what));
    }
}

3.3、使用状态机

MyStateMachine stateMachine = new MyStateMachine("MyStateMachine");
stateMachine.start();
// 发送消息切换状态
stateMachine.sendMessage(MSG_START); // 切换到工作状态
stateMachine.sendMessage(MSG_PAUSE); // 切换到暂停状态
stateMachine.sendMessage(MSG_STOP);  // 切换到空闲状态

4、状态转换与消息处理

4.1、状态转换规则

- transitionTo(State):立即切换到目标状态

- 状态切换时会自动调用当前状态的 exit() 和目标状态的 enter()

- 状态切换后,后续消息由新状态处理

4.2、消息处理流程

1. 消息发送到状态机

2. 当前状态处理消息

3. 如果当前状态返回 false,交给父状态处理

4. 如果所有状态都返回 false,消息被丢弃

5. 处理过程中可以调用 transitionTo() 切换状态

4.3、延迟消息

// 发送延迟消息
sendMessageDelayed(obtainMessage(MSG_TIMEOUT), 5000);
// 在状态中处理超时
@Override
public boolean processMessage(Message msg) {
    if (msg.what == MSG_TIMEOUT) {
        // 处理超时逻辑
        transitionTo(mIdleState);
        return true;
    }
    return false;
}

4.4、消息回收

// 移除特定消息
removeMessages(MSG_TIMEOUT);
// 移除所有消息
removeMessages();

5、实际应用场景

5.1、网络连接状态管理

class NetworkStateMachine extends StateMachine {
    private DisconnectedState mDisconnectedState = new DisconnectedState();
    private ConnectingState mConnectingState = new ConnectingState();
    private ConnectedState mConnectedState = new ConnectedState();
    
    public NetworkStateMachine() {
        super("NetworkStateMachine");
        
        addState(mDisconnectedState);
        addState(mConnectingState);
        addState(mConnectedState);
        
        setInitialState(mDisconnectedState);
    }
    
    class DisconnectedState extends State {
        @Override
        public boolean processMessage(Message msg) {
            if (msg.what == MSG_CONNECT) {
                transitionTo(mConnectingState);
                return true;
            }
            return false;
        }
    }
    
    class ConnectingState extends State {
        @Override
        public void enter() {
            // 开始连接
            connectToServer();
            // 设置连接超时
            sendMessageDelayed(obtainMessage(MSG_TIMEOUT), 10000);
        }
        
        @Override
        public boolean processMessage(Message msg) {
            switch (msg.what) {
                case MSG_CONNECTED:
                    transitionTo(mConnectedState);
                    return true;
                case MSG_TIMEOUT:
                case MSG_DISCONNECT:
                    transitionTo(mDisconnectedState);
                    return true;
            }
            return false;
        }
    }
    
    class ConnectedState extends State {
        @Override
        public void enter() {
            // 连接成功,开始工作
            startWork();
        }
        
        @Override
        public void exit() {
            // 断开连接,清理资源
            stopWork();
        }
        
        @Override
        public boolean processMessage(Message msg) {
            if (msg.what == MSG_DISCONNECT) {
                transitionTo(mDisconnectedState);
                return true;
            }
            return false;
        }
    }
}

5.2、播放器状态管理

class PlayerStateMachine extends StateMachine {
    private IdleState mIdleState = new IdleState();
    private PreparedState mPreparedState = new PreparedState();
    private PlayingState mPlayingState = new PlayingState();
    private PausedState mPausedState = new PausedState();
    
    public PlayerStateMachine() {
        super("PlayerStateMachine");
        
        addState(mIdleState);
        addState(mPreparedState);
        addState(mPlayingState);
        addState(mPausedState);
        
        setInitialState(mIdleState);
    }
}

6、最佳实践与注意事项

6.1、设计原则

- 每个状态职责单一,避免状态过于复杂

- 合理使用状态层级,提取公共逻辑到父状态

- 状态转换要清晰,避免循环依赖

- 消息处理要及时,避免消息堆积

6.2、性能优化

- 避免在 enter() 和 exit() 中执行耗时操作

- 合理使用延迟消息,及时清理不需要的消息

- 状态机运行在独立线程,注意线程安全

- 避免频繁创建和销毁状态机

6.3、调试技巧

- 在每个状态的 enter() 和 exit() 中添加日志

- 记录状态转换和消息处理过程

- 使用 getName() 标识不同的状态机实例

- 监控消息队列大小,避免内存泄漏

6.4、常见问题

问题1:状态转换死循环

解决:检查 transitionTo() 调用逻辑,避免在 enter() 中立即切换状态

问题2:消息处理不及时

解决:检查是否有耗时操作阻塞消息处理,考虑使用异步处理

问题3:内存泄漏

解决:及时调用 quit() 退出状态机,清理延迟消息

6.5、总结

StateMachine 是 Android 提供的强大状态管理工具,通过消息驱动和状态模式,可以优雅地管理复杂的状态转换逻辑。合理使用 StateMachine 可以使代码结构更清晰,状态管理更可靠。

关键要点:

        - 继承 State 定义具体状态

        - 继承 StateMachine 创建状态机

        - 使用 transitionTo() 切换状态

        - 合理使用状态层级结构

        - 注意性能优化和内存管理

掌握 StateMachine 的使用,对于开发复杂业务逻辑、网络连接管理、播放器控制等场景非常有帮助,是 Android 高级开发者必备的技能之一。

相关推荐

精选
ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager
Android

ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager

ViewPager1、ViewPagerandroidx.viewpager.widget.ViewPager,Android中使用非常广泛的控件,可以说是APP必备:首次打开引导页、页面Banner广告等。常用方法:setAdapter() 设置适配器setOffscreenPageLimit() 设置缓存的页面个数,默认是 1setCurrentItem() 跳转到特定的页面setOnPage

1.1k
获取Android内置WebView内核版本
Android

获取Android内置WebView内核版本

获取Android内置WebView内核版本竟然能遇到这样奇葩的事情,网页用的技术过于新颖,以至于只支持高版本Chromium内核的,低版本安卓系统中内置的内核版本较低,无法加载前端页面。1、设置查看在系统设置里 > 应用 > 应用管理 > 显示系统应用,查看WebView组件:2、页面查看通过WebView发起的网络请求,都会带上浏览器的UA,通常页面都可以通过UA判断浏览器的内核版本。这里有两

1.1w
Android 14适配总结
Android

Android 14适配总结

Android 14适配总结毕业工作至今已经适配了三个Android大版本,从Android 11到Android 12、再到Android 13。2023年,Google即将推出的Android 14,上半年已经开始第一批适配。现在,第四个Android版本已经适配完,总结记录一下。1、Android 14计划Google一般会在2月份对外发布预告,同时放出开发者预览版。“拉通”各大平台、厂商以

1.1w