首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从KMM模块获取applicationContext

从KMM模块获取applicationContext
EN

Stack Overflow用户
提问于 2021-02-19 08:02:57
回答 3查看 516关注 0票数 1

我目前正在开发一个简单的KMM模块,它需要Context来执行一些操作。我知道如何通过扩展Application类和进行依赖注入来实现这一点。我现在要做的是什么-让这个模块开箱即用,而不需要修改manifest或在启动时进行手动注入。我只是想知道这样做是不是一种糟糕的做法:

代码语言:javascript
复制
@SuppressLint("StaticFieldLeak")
object SomeUtil {

    private val context = Activity().applicationContext

}

由于applicationContext返回了整个应用程序的Context,而我们只初始化了一次,会不会有泄漏?或者,还有其他一些要点不能做到吗?

也许还有一些其他的可能性可以从模块中获取应用程序上下文?我见过一些从线程中检索它的例子,但据我所知,这将会(或已经)被弃用。

UPD:这会导致错误。Activity()似乎就是null。那么,在没有DI和"MyApplication“的情况下,如何实现这一点呢?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-03-03 07:35:57

这是android库中的一个常见问题--如何在不访问应用程序代码库的情况下获取应用程序上下文?这就是为什么您经常在Application.onCreate()中使用诸如SharedPrefHelper.init(applicationContext)之类的内容初始化库的原因

由于KMM共享代码是一个库,因此您会遇到类似的问题。Android app startup是一个androidx库,用来解决这个问题(以及提高启动性能)。

粗略示例(共享代码中的所有内容):

代码语言:javascript
复制
// In androidMain
class MySqlDelightInitialiser : Initializer<SqlDriver> {
    override fun create(context: Context): SqlDriver {
        val driver = createDriver(context)
        MyLibraryObject.init(context, driver)
        return driver
    }

    override fun dependencies(): List<Class<out Initializer<*>>> {
        return emptyList()
    }
}

// In androidMain/AndroidManifest
<application>
    <provider
        android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.sql-delight-initialiser"
        android:exported="false"
        tools:node="merge"
        tools:replace="android:authorities"
        >
        <meta-data
            android:name="my.package.SqlDelightInitialiser"
            android:value="androidx.startup"
            />
    </provider>
</application>
票数 1
EN

Stack Overflow用户

发布于 2021-02-20 00:38:09

好吧,我首先要说的是,这并不是一个KMM问题。这只适用于Android代码。

据我所知,如果没有一些不成熟的解决方案,就没有办法静态地、全局地访问应用程序上下文。这是一个长期存在的问题,实际上并没有一个好的解决方案。

Crashlytics做到了(did?)注册ContentProvider的唯一目的是获取应用程序并使其可用,这是一件奇怪的事情。假设您是作为aar发布的,它将为您注册ContentProvider。

https://firebase.googleblog.com/2016/12/how-does-firebase-initialize-on-android.html

我不建议你这么做。我非常喜欢自己配置库上下文init,但是您可以尝试ContentProvider方法。

票数 4
EN

Stack Overflow用户

发布于 2021-02-20 00:57:16

简而言之:将其注入到构造函数中或作为方法参数:

代码语言:javascript
复制
class SomeUtil(private val context: Context) {
   ....
}

object SomeUtil {
   fun someMethod(context: Context) { .... }
}

上下文(但也包括Activity、Application、Service)实例是由Android框架创建和销毁的,手动创建实例(或模拟)可能会在编译时工作,但它们会在运行时导致异常

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66269937

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档