如何从CountDownTimer返回布尔值?加速度幅值检测场景求助
解决CountDownTimer内部类无法向外传递检测结果的问题
首先得指出你代码里的两个核心问题:
lying_on_floor是onTick方法内的局部变量,外部方法完全访问不到;而且内部类里的局部变量默认是final的,就算你在外部方法定义这个变量,也没法直接在内部类里修改它(除非用成员变量,但还有更严重的问题)。CountDownTimer是异步执行的——你调用.start()之后,low_high_Detection方法会立刻往下走,此时计时还没开始,lying_on_floor根本没被赋值,直接返回false,完全起不到5秒内检测的作用。
针对这个场景,最常用也最优雅的解决方式是使用回调接口,把异步执行的结果传递出去。具体步骤如下:
1. 定义回调接口
先创建一个接口,用来传递检测结果:
public interface DetectionCallback { void onDetectionResult(boolean isLyingOnFloor); }
2. 修改检测方法
把原来的返回值去掉,换成接收回调参数,同时在计时过程中记录检测结果,最后在onFinish里通过回调传递结果:
public void low_high_Detection(final double ampA, DetectionCallback callback) { new CountDownTimer(5000, 1000) { // 用内部成员变量记录检测结果,每次onTick都会更新 private boolean lyingOnFloor = false; @Override public void onTick(long millisUntilFinished) { final double low_TH = 9.0, high_TH = 10.5; // 每次计时 tick 时更新检测状态 lyingOnFloor = (ampA > low_TH && ampA < high_TH); } @Override public void onFinish() { Toast.makeText(detect.getBaseContext(), "5 seconds detection over", Toast.LENGTH_SHORT).show(); // 计时结束后,通过回调把最终结果传出去 callback.onDetectionResult(lyingOnFloor); } }.start(); }
3. 调用检测方法
调用的时候,通过匿名内部类(或者Lambda表达式,Java 8+支持)实现回调接口,在回调里处理结果:
// 传入你的加速度幅值和回调实现 low_high_Detection(yourAmpValue, new DetectionCallback() { @Override public void onDetectionResult(boolean isLyingOnFloor) { // 在这里处理检测结果 if (isLyingOnFloor) { // 符合条件,执行对应逻辑 // 比如:Toast.makeText(... "检测到符合条件的幅值" ...).show(); } else { // 不符合条件的逻辑 } } });
其他可选方案
如果你的项目使用了Android Jetpack,也可以用LiveData来观察结果,这种方式在MVVM架构里更常用:
// 在你的类里定义LiveData成员变量 private MutableLiveData<Boolean> detectionResult = new MutableLiveData<>(); // 提供外部观察的方法 public LiveData<Boolean> getDetectionResult() { return detectionResult; } public void low_high_Detection(final double ampA) { new CountDownTimer(5000, 1000) { private boolean lyingOnFloor = false; @Override public void onTick(long millisUntilFinished) { final double low_TH = 9.0, high_TH = 10.5; lyingOnFloor = (ampA > low_TH && ampA < high_TH); } @Override public void onFinish() { Toast.makeText(detect.getBaseContext(), "5 seconds detection over", Toast.LENGTH_SHORT).show(); // 用postValue把结果通知给观察者(确保在主线程执行) detectionResult.postValue(lyingOnFloor); } }.start(); }
然后在Activity/Fragment里观察结果:
// 假设你的类实例是detectInstance detectInstance.getDetectionResult().observe(this, isLying -> { // 处理检测结果 if (isLying) { // do something } });
总结一下:异步操作的结果不能用同步返回值的方式获取,必须通过回调、LiveData这类异步通知机制来传递结果,这是Android处理异步任务的标准思路。
内容的提问来源于stack exchange,提问作者Enix Low
相关产品推荐
相关产品推荐

