android - 访问单例内部的应用程序上下文

标签 android kotlin

我有一个单例,用于打开 JSON Assets 并将其作为列表返回。我需要访问应用程序上下文才能使用 Assets 管理器。我无法传递上下文,因为我是从 View 模型调用它,而 View 模型无权访问应用程序上下文。我做了很多搜索,但似乎找不到答案。

import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory

object ProgramListService {
    fun getProgramList(): List<ProgramList>? {

        val moshi = Moshi.Builder()
            .add(KotlinJsonAdapterFactory())
            .build()
        
        val json = context.assets.open("programs/home.json").bufferedReader().use{ it.readText() }
        val listType = Types.newParameterizedType(List::class.java, ProgramList::class.java)
        val adapter: JsonAdapter<List<ProgramList>> = moshi.adapter(listType)

        return adapter.fromJson(json)
    }
}

最佳答案

ViewModel 中的上下文不好,甚至应用程序上下文也不好,AndroidViewModel 也不好用。因此,您可以将 AssetManager 传递到 ViewModel 中,然后 ViewModel 可以将其传递到 ProgramListService 中,从而避免了对上下文的需要,但在 View 模型中使用 Assets 管理器仍然有点奇怪。

因此,您可以跳过 View 模型并将应用程序上下文直接传递到单例 ProgramListService 中。

object ProgramListService {
    lateinit var application: Application // Add this

    ...
}

然后从您的 Activity 的 onCreate 或任何最适合您的项目的地方,

ProgramListService.application = context.applicationContext as Application

或者像@Tenfour04建议的应用程序可以安全地创建全局属性

关于android - 访问单例内部的应用程序上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63568157/

相关文章:

android - here.com mapmarker setTitle 未显示在 map 上

Android-Kotlin- 按钮作为后退按钮

android - 将监听器重置为父 Activity 以重新创建 fragment

java - 我应该使用什么来代替 PostgreSQL11Dialect?

kotlin - 基于 bool 值的Rx Java调用Api

android - 如何在不同的类之间共享相同的构造函数,也就是在接口(interface)中定义构造函数?

android - 使用 for 循环填充 Kotlin 中的列表

java - ProGuard - 仅保持资源处于 Activity 状态

android - 相机预览倒置

android - 无法在 Kotlin Android 中的 Observable 上调用 from() 运算符