如何在Android的Datasource类中访问string-array类型资源
问题根因
你遇到的报错有两个核心原因:
Resources.getStringArray()是实例方法,不是静态方法,不能直接通过Resources类名调用,必须拿到Resources实例才能调用- 普通自定义类默认没有Android的
Context引用,getResources()是Context类的方法,你在无Context的类里自然调用不到
解决方案
给你的Datasource类添加带Context的构造函数,依赖外部传入的Context实例访问资源,推荐传入ApplicationContext避免内存泄漏,修改后的代码如下:
package com.example.anime5echaractersheet.data import android.content.Context import com.example.anime5echaractersheet.R class Datasource(private val context: Context) { private val raceList: Array<String> = context.resources.getStringArray(R.array.races) val subraceMap: Map<String, Int> = mapOf( raceList[0] to R.array.archfiend_subraces // 后续其他种族的映射可以继续在这里添加 ) // 可选:封装获取对应子种族数组的方法 fun getSubraces(raceName: String): Array<String>? { val arrayResId = subraceMap[raceName] ?: return null return context.resources.getStringArray(arrayResId) } }
实例化注意事项
在你需要创建Datasource实例的地方,优先传入ApplicationContext:
// 比如在Activity中初始化 val datasource = Datasource(applicationContext) // 比如在Application类中全局初始化 class MyApp : Application() { val datasource by lazy { Datasource(this) } }
可选优化(自动构建映射表)
如果你的子种族数组命名严格遵循[种族名小写]_subraces的规则,可以不用手动逐个写键值对,通过getIdentifier动态匹配资源ID,简化代码:
val subraceMap: Map<String, Int> = raceList.associateWith { raceName -> val resName = "${raceName.lowercase()}_subraces" context.resources.getIdentifier(resName, "array", context.packageName) }.filterValues { it != 0 } // 过滤掉不存在的子种族资源
内容的提问来源于stack exchange,提问作者friend.code
相关产品推荐
相关产品推荐

