You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()?

问题原因与解决方案

核心错误点

  1. UI操作在非UI线程执行:TimerTask的run()方法运行在后台线程,而finishAndRemoveTask()、startActivity()都是必须在主线程执行的UI操作,直接调用会导致异常,Activity B无法正常启动。
  2. 任务栈销毁顺序错误:先调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:39:55