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

Android Studio中如何实现每秒运行的Java方法以检测ToggleButton状态?

每秒检测ToggleButton并触发震动的可行实现方案

递归调用导致崩溃的核心原因是:每次递归都会在调用栈中新增方法帧,持续运行后会耗尽栈内存,抛出StackOverflowError。以下是两种安全可靠的实现方式:

方案一:使用Handler实现主线程定时任务

Handler是Android中处理主线程定时任务的常用方式,不会产生栈溢出问题,且天然支持UI操作:

private Handler mCheckHandler = new Handler(Looper.getMainLooper());
private Runnable mCheckTask = new Runnable() {
    @Override
    public void run() {
        checkToggleStateAndVibrate();
        // 1秒后再次执行任务
        mCheckHandler.postDelayed(this, 1000);
    }
};

// 核心检测与震动逻辑
private void checkToggleStateAndVibrate() {
    // 仅当ToggleButton处于选中状态时继续判断
    if (!tb.isChecked()) return;

    // 获取当前小时与分钟
    Calendar now = Calendar.getInstance();
    int curHour = now.get(Calendar.HOUR_OF_DAY);
    int curMin = now.get(Calendar.MINUTE);

    // 匹配设定时间时触发震动
    if (curHour == hour && curMin == minutes) {
        // 检查震动权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.VIBRATE) 
                == PackageManager.PERMISSION_GRANTED) {
            Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
            if (vibrator != null) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    // Android 8.0及以上使用VibrationEffect
                    vibrator.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE));
                } else {
                    // 低版本直接调用vibrate方法
                    vibrator.vibrate(500);
                }
            }
        }
    }
}

// 在Activity生命周期中启动/停止任务,避免内存泄漏
@Override
protected void onResume() {
    super.onResume();
    mCheckHandler.post(mCheckTask);
}

@Override
protected void onPause() {
    super.onPause();
    mCheckHandler.removeCallbacks(mCheckTask);
}

方案二:使用ScheduledExecutorService实现后台定时任务

适合需要在后台执行检测逻辑的场景,若需访问UI组件需切换到主线程:

private ScheduledExecutorService mScheduler = Executors.newSingleThreadScheduledExecutor();
private ScheduledFuture<?> mCheckFuture;

// 启动定时任务
private void startScheduledCheck() {
    mCheckFuture = mScheduler.scheduleAtFixedRate(() -> {
        // 切换到主线程操作UI组件
        runOnUiThread(this::checkToggleStateAndVibrate);
    }, 0, 1, TimeUnit.SECONDS);
}

// 停止定时任务
private void stopScheduledCheck() {
    if (mCheckFuture != null && !mCheckFuture.isCancelled()) {
        mCheckFuture.cancel(true);
    }
}

// 同样在生命周期中管理任务
@Override
protected void onResume() {
    super.onResume();
    startScheduledCheck();
}

@Override
protected void onPause() {
    super.onPause();
    stopScheduledCheck();
}

// 复用方案一中的checkToggleStateAndVibrate方法

必要配置

在AndroidManifest.xml中声明震动权限:

<uses-permission android:name="android.permission.VIBRATE" />

注意:VIBRATE权限属于Android正常权限,无需动态申请,但仍建议通过checkSelfPermission做兼容性检查,避免特殊场景下的权限问题。

内容的提问来源于stack exchange,提问作者SKYWALKER

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 03:02:50