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

Android多模块应用:如何在高分模块获取游戏的本地化标题?

跨模块获取本地化游戏标题的可行方案

针对你用Compose+Koin构建多模块游戏应用时,高分模块无法访问游戏模块资源以显示本地化标题的问题,以下是几个实用解决方案:

方案1:修改GameApi,直接返回本地化字符串

调整GameApi的title()方法,让它接收Context参数并返回已本地化的字符串,而非资源ID。游戏模块的实现类可以直接访问自身资源,实时根据当前语言环境生成标题。

修改后的GameApi接口

interface GameApi {
    fun registerGame(
        navGraphBuilder: NavGraphBuilder,
        navController: NavHostController,
        modifier: Modifier = Modifier
    )

    fun gameRoute(): GameRoutes
    fun title(context: Context): String
    fun id(): Int
}

游戏模块实现示例

class MeaningGameApi : GameApi {
    override fun title(context: Context): String {
        return context.getString(R.string.title_meaning_game)
    }

    // 其他方法实现...
}

高分模块调用示例

@Composable
fun HighScoreScreen(gameApis: List<GameApi>) {
    val context = LocalContext.current
    LazyColumn {
        items(gameApis) { gameApi ->
            Text(text = gameApi.title(context))
        }
    }
}

这个方案无需额外存储或中间层,直接利用Context实时获取对应语言的字符串,适配语言切换场景,是最简洁的解决方案。

方案2:通过Core模块提供资源访问桥接

如果不想修改GameApi的现有方法,可以在Core模块定义一个资源访问接口,由App模块提供实现,高分模块通过这个接口解析游戏模块返回的资源ID。

Core模块定义资源访问接口

interface ResourceProvider {
    fun getString(resId: Int): String
}

// Koin注入配置(Core模块)
val coreModule = module {
    single<ResourceProvider> { AndroidResourceProvider(get()) }
}

App模块实现接口

class AndroidResourceProvider(private val context: Context) : ResourceProvider {
    override fun getString(resId: Int): String {
        return context.getString(resId)
    }
}

高分模块调用示例

@Composable
fun HighScoreScreen(gameApis: List<GameApi>, resourceProvider: ResourceProvider) {
    LazyColumn {
        items(gameApis) { gameApi ->
            Text(text = resourceProvider.getString(gameApi.title()))
        }
    }
}

此方案保持GameApi原有结构,通过Core模块做资源访问的中转,适合需要统一管理资源访问逻辑的场景。

方案3:预注册本地化标题到Core缓存

基于你之前尝试的数据库思路优化,在游戏模块注册导航时,传入Context将本地化标题存入Core模块的内存缓存,高分模块直接从缓存读取。

Core模块定义标题管理器

class GameMetadataManager {
    private val gameTitles = mutableMapOf<Int, String>()

    fun saveGameTitle(gameId: Int, title: String) {
        gameTitles[gameId] = title
    }

    fun getGameTitle(gameId: Int): String? {
        return gameTitles[gameId]
    }
}

// Koin注入配置(Core模块)
val coreModule = module {
    single { GameMetadataManager() }
}

修改GameApi的registerGame方法

interface GameApi {
    fun registerGame(
        navGraphBuilder: NavGraphBuilder,
        navController: NavHostController,
        context: Context,
        modifier: Modifier = Modifier
    )

    // 其他方法不变...
}

游戏模块注册时保存标题

class MeaningGameApi(private val metadataManager: GameMetadataManager) : GameApi {
    override fun registerGame(
        navGraphBuilder: NavGraphBuilder,
        navController: NavHostController,
        context: Context,
        modifier: Modifier
    ) {
        // 导航注册逻辑...
        metadataManager.saveGameTitle(id(), context.getString(title()))
    }

    // 其他方法实现...
}

高分模块读取缓存标题

@Composable
fun HighScoreScreen(gameApis: List<GameApi>, metadataManager: GameMetadataManager) {
    LazyColumn {
        items(gameApis) { gameApi ->
            Text(text = metadataManager.getGameTitle(gameApi.id()) ?: "Unknown Game")
        }
    }
}

注意:此方案需要在语言切换时重新触发游戏注册,否则缓存的标题会保持旧语言版本,适合对性能要求较高、语言切换不频繁的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 23:04:57