Android 10+中从Service的onSensorChanged启动Activity崩溃求助
问题分析与解决方案
你的代码崩溃的核心原因有三个,和Android 10+适配也有关联,逐个解决:
1. 条件判断完全写反
你当前的逻辑是只要重复次数没到上限就跳转,传感器回调频率极高(每秒几十次),会瞬间触发无数次startActivity,直接导致程序崩溃。必须把条件改成达到或超过设定次数才跳转。
2. 传感器回调不在UI线程
onSensorChanged运行在系统传感器线程,不是UI线程,Android 10+对非UI线程操作Activity的限制更严格,直接调用startActivity会触发线程安全异常,必须切换到UI线程执行。
3. 滥用FLAG_ACTIVITY_NEW_TASK
如果当前上下文是Activity,不需要添加这个标记,它是给非Activity上下文(比如Service)启动Activity用的,滥用会导致任务栈混乱,甚至触发后台启动限制。
正确实现代码
override fun onSensorChanged(event: SensorEvent?) { val currentReps = repetitionTracker.getNumberOfRepetitions() // 修正条件:达到目标次数才触发 if (currentReps >= maxRepetitions) { // 切换到UI线程执行跳转 runOnUiThread { val intent = Intent(this@YourCurrentActivity, End::class.java) startActivity(intent) // 跳转后立即注销传感器监听,避免重复触发 sensorManager.unregisterListener(this) // 可选:如果不需要保留当前页面,直接finish finish() } } }
替代方案:用LiveData解耦(推荐)
把计数逻辑和页面跳转逻辑分离,避免在传感器回调中直接操作UI,更符合Android架构规范:
第一步:在RepetitionTracker中用LiveData暴露计数
class RepetitionTracker { private val _repetitionCount = MutableLiveData<Int>(0) val repetitionCount: LiveData<Int> = _repetitionCount fun getNumberOfRepetitions(): Int { return _repetitionCount.value ?: 0 } // 更新计数时调用这个方法 fun incrementRepetition() { _repetitionCount.postValue(getNumberOfRepetitions() + 1) } }
第二步:在Activity中观察计数变化
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ...其他初始化代码 repetitionTracker.repetitionCount.observe(this) { count -> if (count >= maxRepetitions) { val intent = Intent(this, End::class.java) startActivity(intent) sensorManager.unregisterListener(this) finish() } } }
Android 10+适配注意事项
如果你的传感器监听是在后台Service中,Android 10+不允许直接启动Activity,必须先显示一个前台Notification,再通过Notification的PendingIntent跳转。但你的场景是运动App,应该是在前台Activity中监听传感器,所以上面的代码完全适用。
内容的提问来源于stack exchange,提问作者user3784015
相关产品推荐
相关产品推荐

