Android调用finishAndRemoveTask后Activity B无法启动问题求助
问题描述
测试环境:小米Mi 9T(Android 10,API 29)
流程说明:
- 在Activity A中启动系统设置页面开启无障碍权限,需进入两层设置子页面完成操作。
- Activity A通过定时器持续检测权限是否授予,检测通过后调用
finishAndRemoveTask()关闭Activity A及所有设置页面,但Activity B始终无法启动。
核心代码片段
启动设置页面的代码:
Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); startActivity(intent);
定时器检测权限的逻辑:
public void timerStart() { this.timer.scheduleAtFixedRate(new TimerTask() { public void run() { if (isAccessibilityEnabled(ActivityA.this)) { timer.cancel(); finishAndRemoveTask(); Intent intent = new Intent(ActivityA.this, ActivityB.class); startActivity(intent); return; } } }, 0, 500); }
完整Activity A代码
public class ActivityA extends AppCompatActivity { private Button btn_permission; private Timer timer = new Timer(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView((int) R.layout.activity_a); timerStart(); this.btn_permission = (Button) findViewById(R.id.btn_permission); this.btn_permission.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); startActivity(intent); } }); } @Override public void onDestroy() { super.onDestroy(); } public void timerStart() { this.timer.scheduleAtFixedRate(new TimerTask() { public void run() { if (isAccessibilityEnabled(ActivityA.this)) { timer.cancel(); finishAndRemoveTask(); Intent intent = new Intent(ActivityA.this, ActivityB.class); startActivity(intent); return; } } }, 0, 500); } public static boolean isAccessibilityEnabled(Context context) { // 权限检测逻辑 } }
现象与关键Logcat错误
授予权限后应用直接完全关闭,未跳转至Activity B。关键错误日志:
2023-04-03 14:33:47.021 1810-4082 InputDispatcher system_server E Window handle Window{6bde395 u0 com.android.settings/com.android.settings.SubSettings} has no registered input channel 2023-04-03 14:33:47.259 28960-28960 ActivityThread com.android.settings E Activity com.android.settings.SubSettings has leaked IntentReceiver com.android.settings.accessibility.InstalledAccessibilityService$2@7f06f04 that was originally registered here. Are you missing a call to unregisterReceiver()?
问题原因与解决方案
核心错误点
- UI操作在非UI线程执行:
TimerTask的run()方法运行在后台线程,而finishAndRemoveTask()、startActivity()都是必须在主线程执行的UI操作,直接调用会导致异常,Activity B无法正常启动。 - 任务栈销毁顺序错误:先调用
finishAndRemoveTask()会销毁当前应用的整个任务栈,后续启动Activity B时没有有效的任务栈承载,导致启动失败。
修正方案
1. 切回主线程执行UI操作
使用runOnUiThread()将finish和启动Activity的逻辑切换到主线程。
2. 调整执行顺序:先启动Activity B,再销毁任务栈
确保Activity B有可依附的任务栈,避免因任务栈被提前销毁导致启动失败。
3. 清理定时器资源
在onDestroy()中取消定时器并释放资源,避免内存泄漏。
修正后的代码
public class ActivityA extends AppCompatActivity { private Button btn_permission; private Timer timer = new Timer(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_a); timerStart(); btn_permission = findViewById(R.id.btn_permission); btn_permission.setOnClickListener(v -> { Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); startActivity(intent); }); } @Override protected void onDestroy() { super.onDestroy(); if (timer != null) { timer.cancel(); timer.purge(); } } public void timerStart() { timer.scheduleAtFixedRate(new TimerTask() { public void run() { if (isAccessibilityEnabled(ActivityA.this)) { timer.cancel(); // 切回主线程执行UI操作 runOnUiThread(() -> { Intent intent = new Intent(ActivityA.this, ActivityB.class); startActivity(intent); // 先启动ActivityB,再销毁当前任务栈 finishAndRemoveTask(); }); return; } } }, 0, 500); } public static boolean isAccessibilityEnabled(Context context) { // 标准无障碍权限检测逻辑示例 AccessibilityManager am = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE); List<AccessibilityServiceInfo> enabledServices = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK); for (AccessibilityServiceInfo service : enabledServices) { if (service.getResolveInfo().serviceInfo.packageName.equals(context.getPackageName())) { return true; } } return false; } }
优化建议
避免使用Timer轮询检测权限,改用ContentObserver监听无障碍设置变化,更高效且符合Android最佳实践:
private ContentObserver accessibilityObserver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_a); // 注册ContentObserver监听无障碍设置变化 accessibilityObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { @Override public void onChange(boolean selfChange) { super.onChange(selfChange); if (isAccessibilityEnabled(ActivityA.this)) { getContentResolver().unregisterContentObserver(this); Intent intent = new Intent(ActivityA.this, ActivityB.class); startActivity(intent); finishAndRemoveTask(); } } }; getContentResolver().registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES), true, accessibilityObserver ); } @Override protected void onDestroy() { super.onDestroy(); if (accessibilityObserver != null) { getContentResolver().unregisterContentObserver(accessibilityObserver); } }
内容的提问来源于stack exchange,提问作者araraujo
相关产品推荐
相关产品推荐

