Android中从Java调用Kotlin挂起函数始终未执行问题排查
问题:Java调用Kotlin挂起函数时,内部挂起函数未执行
我尝试实现Java调用Kotlin挂起函数,调试时能进入readStepsByTimeRange方法,但innerReadStepsByTimeRange始终未被调用。
被Java调用的Kotlin类
class StepReaderUtils { companion object { @OptIn(DelicateCoroutinesApi::class) fun readStepsByTimeRange( healthConnectClient: HealthConnectClient, startTime: Instant, endTime: Instant ) : CompletableFuture<Long> = GlobalScope.future { innerReadStepsByTimeRange(healthConnectClient, startTime, endTime) } private suspend fun innerReadStepsByTimeRange ( healthConnectClient: HealthConnectClient, startTime: Instant, endTime: Instant ) : Long { var totalStepsCount = 0L val response = healthConnectClient.readRecords( ReadRecordsRequest( StepsRecord::class, timeRangeFilter = TimeRangeFilter.between(startTime, endTime) ) ) for (stepRecord in response.records) { totalStepsCount += stepRecord.count; } return totalStepsCount } } }
Java调用代码
CompletableFuture<Long> totalStepsCountCF = StepReaderUtils.Companion.readStepsByTimeRange( healthConnectClient, startDate, endDate); return totalStepsCountCF.get();
Gradle模块依赖
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.8.0' implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0' implementation "androidx.health.connect:connect-client:1.0.0-alpha08" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.6.4" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
问题分析与解决方案
可能的原因及修复步骤:
- 替换GlobalScope为指定调度器的CoroutineScope
GlobalScope的协程不受生命周期管理,默认调度器可能因环境差异导致执行异常。建议改用明确指定IO调度器的自定义Scope:
@OptIn(DelicateCoroutinesApi::class) fun readStepsByTimeRange( healthConnectClient: HealthConnectClient, startTime: Instant, endTime: Instant ) : CompletableFuture<Long> = CoroutineScope(Dispatchers.IO).future { innerReadStepsByTimeRange(healthConnectClient, startTime, endTime) }
- 修复依赖版本不匹配问题
Kotlin 1.8.0与kotlinx-coroutines 1.6.4存在兼容性隐患,建议升级协程依赖到与Kotlin版本匹配的稳定版(如1.7.3):
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.3" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
- 添加异常捕获排查根因
CompletableFuture.get()会抛出ExecutionException,未捕获时可能误以为内部函数未执行,建议添加异常捕获查看真实问题:
try { CompletableFuture<Long> totalStepsCountCF = StepReaderUtils.Companion.readStepsByTimeRange( healthConnectClient, startDate, endDate); return totalStepsCountCF.get(); } catch (ExecutionException e) { e.getCause().printStackTrace(); throw e; } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw e; }
- 验证HealthConnect权限与参数
确保已申请读取步数的HealthConnect权限,且startTime早于endTime,否则readRecords可能抛出异常导致协程提前终止。
内容的提问来源于stack exchange,提问作者Mert Serimer
相关产品推荐
相关产品推荐

