Android 10及以上版本中启动的无障碍服务无法正常停止如何解决
你当前代码存在3个核心错误,是导致高版本系统服务无法停止的根本原因:
核心错误说明
手动实例化Service调用生命周期方法
你在PerformTaskService.onDestroy()中写了new StatusBarService().onDestroy(),这是完全错误的用法:Service是Android系统管理的组件,所有运行中的Service实例均由系统创建,你手动new出来的实例和当前正在运行的无障碍服务没有任何关联,调用它的onDestroy()不会对实际运行的服务产生任何作用,反而可能引入内存泄漏风险。
onDestroy中重复调用停止方法导致流程异常
Service的onDestroy()是系统触发的销毁回调,你不需要在这个回调里反复调用stopSelf、stopSelfResult这类方法,重复调用在高版本Android中可能导致销毁流程异常卡住。AccessibilityService不能用普通服务逻辑控制启停
StatusBarService继承自AccessibilityService,它的生命周期完全由系统和用户授权控制,普通的startService、stopService对它无效,也不能直接通过代码销毁,必须用无障碍服务专属的API控制。
修复步骤
步骤1:修复PerformTaskService的销毁逻辑
修改PerformTaskService的onDestroy方法如下:
@Override public void onDestroy() { // 此处仅需释放当前服务所有资源:取消后台任务、注销广播/观察者、移除静态引用等 // 移除所有冗余的stopSelf相关调用 super.onDestroy(); }
步骤2:适配AccessibilityService的停止逻辑
如果需要代码主动停止正在运行的StatusBarService,调用无障碍服务专属的disableSelf()方法,修改代码如下:
public class StatusBarService extends AccessibilityService { // 用弱引用持有实例避免内存泄漏 private static WeakReference<StatusBarService> runningInstance; @Override public void onCreate() { super.onCreate(); runningInstance = new WeakReference<>(this); // 保留原有初始化逻辑 } // 对外暴露停止方法 public static void stopRunningService() { if (runningInstance != null && runningInstance.get() != null) { runningInstance.get().disableSelf(); runningInstance.clear(); } } @Override public void onDestroy() { // 销毁前先移除悬浮窗等自定义资源 if (mFloatingView != null) { WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); wm.removeView(mFloatingView); } // 移除冗余的stopSelf调用 super.onDestroy(); } // 保留原有其他逻辑 }
之后修改MainActivity的停止逻辑,先停无障碍服务再停普通服务:
public void stopServices() { // 先停止无障碍服务 StatusBarService.stopRunningService(); // 再停止普通任务服务 stopService(new Intent(getApplicationContext(), PerformTaskService.class)); }
步骤3:适配前台服务规则(如果开启了前台服务)
如果你的PerformTaskService在Android 10+上被设置为前台服务,停止前必须先调用stopForeground,否则服务无法正常销毁:
// 可在PerformTaskService的onDestroy开头添加 stopForeground(true);
同时确认你已经在AndroidManifest.xml中声明了Android 10+需要的前台服务权限:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
步骤4:排查内存泄漏
检查两个服务中是否存在以下会导致服务无法被系统回收的场景:
- 静态变量持有Service的Context引用
- 注册了广播、EventBus、观察者等没有在销毁时注销
- 后台线程、异步任务持有Service引用没有主动取消
内容的提问来源于stack exchange,提问作者kishan antala

