如何在没有应用程序上下文的情况下从资源中读取 json 文件



我正在尝试从 res/raw 文件夹中读取 json 文件,但我不在活动中,它在 Kotlinobject中。如果没有我那里没有的contextapplicationContext,我就无法阅读它。

我尝试创建一个类,在其中使用 Hilt 注入上下文,但这也失败了,因为我无法在我的对象中注入该类。我被困住了,我错过了什么?不会那么难吧?

json 文件目前仅

{
"spacer": 8
}

也许将来会添加更多参数。我想将此值保存在一个对象中(其中包含不是来自 json 的其他值),这样我就不必每次需要时都读取它。该参数用于撰写主题。

您可以尝试使用上下文扩展函数从/assets 文件夹中读取 json 文件:

fun Context.getJsonFromAssets(fileName: String): String? {
val jsonString: String
try {
val inputStream = assets.open(fileName)
val size = inputStream.available()
val buffer = ByteArray(size)
inputStream.read(buffer)
inputStream.close()
jsonString = String(buffer, Charset.defaultCharset())
} catch (e: IOException) {
e.printStackTrace()
return null
}
return jsonString
}

不幸的是,正如Thales在此评论中所说,您可以创建一个EntryPoint来注入 Hilt 提供的任何内容,但您仍然需要applicationContext开始,因此您仍然需要解决对象中没有它的事实。您可以让Application类在其onCreate方法中注入其上下文,对对象使用"初始值设定项"函数,该函数既可以保存需要字符串或其他资源的用例applicationContext,也可以启用诸如在应用程序中注入Hilt提供的任何对象之类的功能。我将给你一个例子,说明你需要如何更改你的应用程序类,以及你的对象是什么样子的。

import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
MyObject.initializeMyObject(applicationContext)
}
}

您的对象可能是这样的:

import android.annotation.SuppressLint
import android.content.Context
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.EntryPointAccessors
import dagger.hilt.components.SingletonComponent
// MyExampleInterface should be properly configured to be provided by Hilt
@EntryPoint
@InstallIn(SingletonComponent::class)
interface MyObjectEntryPoint {
fun myExampleInterface(): MyExampleInterface
}
@SuppressLint("StaticFieldLeak")
object MyObject {
private var myContext: Context? = null
private var injectedDependency: MyExampleInterface? = null
// make sure the context passed is applicationContext to avoid memory leaks
fun initializeMyObject(applicationContext: Context) {
myContext = applicationContext
myContext?.let {
val hiltEntryPoint =
EntryPointAccessors.fromApplication(it, MyObjectEntryPoint::class.java)
injectedDependency = hiltEntryPoint.myExampleInterface()
}
}
fun getResourceFromObject(): String {
return myContext?.getString(R.string.app_name) ?: "Context not injected"
}
fun usingInjectedDependency(): String {
return injectedDependency?.myExampleFunction() ?: "Dependency not injected"
}
}

我不是内存泄漏方面的超级专家,但是如果您确保传递给initializeMyObjectcontext始终是其onCreate方法的applicationContext,那么您就不会遇到任何泄漏问题,因为applicationContext直到应用程序重新启动或被杀死才会发布。

如果你使用的是Koin,你可以做这样的事情:

import android.content.Context
import com.your.app.R
import org.koin.java.KoinJavaComponent.get
object YourObject {
val context: Context = get(Context::class.java)
val yourString = context.getString(R.string.your_string)
// do other stuff with context here
}

您应该注意不要存储此上下文对象,因为它可能会导致内存泄漏,您可以使用它来获取资源,而无需将其分配给任何变量,例如

val yourString = get(Context::class.java).getString(R.string.your_string)

最新更新