Android Kotlin中ML Kit翻译客户端未返回译文问题排查
问题描述
我是Kotlin及Android开发新手,希望根据语言代码将产品成分文本翻译为西班牙语。以下是我的函数代码(忽略西班牙语错误提示):
private fun translateTextToSpanish(ingredients: String, it: String?): String { val opcionesTraductor: TranslatorOptions if(it == "en") opcionesTraductor = TranslatorOptions.Builder() .setSourceLanguage(TranslateLanguage.ENGLISH) .setTargetLanguage(TranslateLanguage.SPANISH) .build() else if(it == "fr") opcionesTraductor = TranslatorOptions.Builder() .setSourceLanguage(TranslateLanguage.FRENCH) .setTargetLanguage(TranslateLanguage.SPANISH) .build() else if(it == "de") opcionesTraductor = TranslatorOptions.Builder() .setSourceLanguage(TranslateLanguage.GERMAN) .setTargetLanguage(TranslateLanguage.SPANISH) .build() else if(it == "it") opcionesTraductor = TranslatorOptions.Builder() .setSourceLanguage(TranslateLanguage.ITALIAN) .setTargetLanguage(TranslateLanguage.SPANISH) .build() else if(it == "pt") opcionesTraductor = TranslatorOptions.Builder() .setSourceLanguage(TranslateLanguage.PORTUGUESE) .setTargetLanguage(TranslateLanguage.SPANISH) .build() else if(it == "ru") opcionesTraductor = TranslatorOptions.Builder() .setSourceLanguage(TranslateLanguage.RUSSIAN) .setTargetLanguage(TranslateLanguage.SPANISH) .build() else opcionesTraductor = TranslatorOptions.Builder() .setSourceLanguage(TranslateLanguage.ENGLISH) .setTargetLanguage(TranslateLanguage.SPANISH) .build() val traductorFinal = Translation.getClient(opcionesTraductor) var traduccion = "" val conditions = DownloadConditions.Builder() .requireWifi() .build() traductorFinal.downloadModelIfNeeded(conditions) .addOnSuccessListener { traductorFinal.translate(ingredients) .addOnSuccessListener { translatedText -> traduccion = translatedText } .addOnFailureListener { val dialog = AlertDialog.Builder(this) dialog.setTitle("🗣 Error en la traducción") dialog.setMessage("Se ha producido un error en la traducción.\n\nVuelve a intentarlo más tarde, y si el problema persiste, contacta con nosotros.") dialog.setNegativeButton("Cerrar", null) dialog.show() } } .addOnFailureListener { val dialog = AlertDialog.Builder(this) dialog.setTitle("🗣 Error en la traducción") dialog.setMessage("Se ha producido un error en la traducción.\n\nVuelve a intentarlo más tarde, y si el problema persiste, contacta con nosotros.") dialog.setNegativeButton("Cerrar", null) dialog.show() } return traduccion }
当前该函数返回空字符串,我使用的是最新版ML Kit API,无法定位问题所在,恳请帮助排查。
问题分析与解决方案
核心问题
ML Kit的downloadModelIfNeeded和translate都是异步操作,函数会在异步任务完成前就执行return traduccion,此时traduccion还是初始的空字符串,所以返回结果为空。
修复方案
不能用同步返回值的方式处理异步操作,需要改用协程(推荐,符合Kotlin现代开发范式)、回调函数或LiveData来获取翻译结果。以下是协程实现方案:
1. 重构为协程函数
private suspend fun translateTextToSpanish(ingredients: String, langCode: String?): String? { // 用when简化语言映射,替代嵌套if-else val sourceLang = when(langCode) { "en" -> TranslateLanguage.ENGLISH "fr" -> TranslateLanguage.FRENCH "de" -> TranslateLanguage.GERMAN "it" -> TranslateLanguage.ITALIAN "pt" -> TranslateLanguage.PORTUGUESE "ru" -> TranslateLanguage.RUSSIAN else -> TranslateLanguage.ENGLISH } val opcionesTraductor = TranslatorOptions.Builder() .setSourceLanguage(sourceLang) .setTargetLanguage(TranslateLanguage.SPANISH) .build() val traductorFinal = Translation.getClient(opcionesTraductor) val conditions = DownloadConditions.Builder() .requireWifi() .build() return try { // 用await()等待异步任务完成,获取同步结果 traductorFinal.downloadModelIfNeeded(conditions).await() traductorFinal.translate(ingredients).await() } catch (e: Exception) { // 统一错误处理 AlertDialog.Builder(this) .setTitle("🗣 Error en la traducción") .setMessage("Se ha producido un error en la traducción.\n\nVuelve a intentarlo más tarde, y si el problema persiste, contacta con nosotros.") .setNegativeButton("Cerrar", null) .show() null } finally { // 释放翻译客户端资源,避免内存泄漏 traductorFinal.close() } }
2. 调用协程函数
需要在协程作用域中调用,比如Activity的lifecycleScope或ViewModel的viewModelScope:
// 在Activity中调用示例 lifecycleScope.launch { val translatedText = translateTextToSpanish("Sample ingredients", "en") translatedText?.let { // 更新UI或处理翻译结果 ingredientTextView.text = it } }
额外优化点
- 用
when表达式替代嵌套if-else,代码更简洁易维护 - 添加
finally块关闭翻译客户端,避免资源泄漏 - 统一错误处理逻辑,减少重复代码
内容的提问来源于stack exchange,提问作者r0dr1
相关产品推荐
相关产品推荐

