簡體   English   中英

從 KMM 模塊獲取 applicationContext

[英]Get applicationContext from a KMM module

我目前正在開發一個簡單的 KMM 模塊,它需要Context才能執行一些操作。 我知道通過擴展Application class 和進行依賴注入來實現這一目標的方法。 我現在要做什么 - 使該模塊開箱即用,無需修改manifest或在啟動時進行手動注入。 我只是想知道這樣做是不是一種不好的做法:

@SuppressLint("StaticFieldLeak")
object SomeUtil {

    private val context = Activity().applicationContext

}

由於applicationContext返回整個應用程序的Context並且我們正在初始化它一次,會不會有泄漏? 還是有其他一些不能做到的點?

也許還有其他一些可能性可以從模塊中獲取應用程序上下文? 我已經看到了一些從線程中檢索它的示例,但據我所知,這將被(或已經)棄用。

UPD:這會導致錯誤。 Activity()似乎是null 那么任何想法如何在沒有 DI 和“MyApplication”的情況下實現這一目標?

好吧,我首先要說這不是一個真正的 KMM 問題。 這僅適用於 Android 代碼。

據我所知,不,沒有一些半駭客的解決方案,就無法靜態地、全局地訪問應用程序上下文。 這是一個長期存在的問題,實際上並沒有很好的解決方案。

Crashlytics 通過注冊一個唯一目的是獲取應用程序並使其可用的 ContentProvider 確實(做了?)一些奇怪的事情。 假設您作為 aar 發布,它會為您注冊 ContentProvider。

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

我不建議這樣做。 我非常喜歡自己配置庫上下文初始化,但您可以嘗試 ContentProvider 路由。

簡短回答:將其注入構造函數或作為方法參數:

class SomeUtil(private val context: Context) {
   ....
}

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

上下文(還有 Activity、Application、Service)實例由 Android 框架創建和銷毀,手動(或模擬)創建實例可能會在編譯時工作,但它們會在運行時導致異常

這是 android 庫中的常見問題 - 如何在不訪問應用程序代碼庫的情況下獲取應用程序上下文? 這就是為什么您經常在Application.onCreate()中使用SharedPrefHelper.init(applicationContext)之類的東西來初始化庫的原因

由於 KMM 共享代碼是一個庫,您會遇到類似的問題。 Android 應用程序啟動是為解決此問題而構建的 androidx 庫(以及提高啟動性能)。

粗略示例(共享代碼中的所有內容):

// 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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM