Skip to content Skip to sidebar Skip to footer

Access Application Context In Companion Object In Kotlin

How can we access application context inside companion object in Android kotlin? I have a companion object inside an abstract class and I want to access context to read Shared Pref

Solution 1:

please see this go to link

classMainApplication : Application() {

    init {
        instance = this
    }

    companionobject {
        privatevar instance: MainApplication? = nullfunapplicationContext() : Context {
            return instance!!.applicationContext
        }
    }

    overridefunonCreate() {
        super.onCreate()
        // initialize for any// Use ApplicationContext.// example: SharedPreferences etc...val context: Context = MainApplication.applicationContext()
    }
}

Solution 2:

Actually I'm working inside an Android library and the class is abstract, so can't go with the already suggested solutions. However, I found way to do that.

  1. Creat a lateinit Context field inside companion object.
abstractclassMyClass{

    companionobject {

        privatelateinitvar context: Context

        funsetContext(con: Context) {
            context=con
        }
    }
}
  1. And then set it after the app has started
publicclassWelcomeActivityextendsAppCompatActivity {

    @OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_welcome);

        MyClass.Companion.setContext(this);
    }
}

Solution 3:

Extends Application class like this

import android.app.Application
import android.content.Context

classMyApplication : Application() {

    overridefunonCreate() {
        super.onCreate()
        MyApplication.appContext = applicationContext
    }

    companionobject {

        lateinitvar appContext: Context
  
    }
}

then get context like this

valcontext= MyApplication.appContext

Solution 4:

There is a super cool article from the guys from Firebase explaining how their SDK gets hold of the context.

Basically my contentprovider looks like this:

/**
 * This content provider is only responsible to inject the application context into the common module.
 */classContextProvider : ContentProvider() {

    companionobject {
        privateval TAG = ContextProvider::class.java.simpleName
    }

    overridefunonCreate(): Boolean {
        context?.let {
            Common.setContext(it)
            returntrue
        }
        Logger.e(TAG, "Context injection to common failed. Context is null! Check ContextProvider registration in the Manifest!")
        returnfalse
    }

    overridefunquery(uri: Uri, projection: Array<String>?, selection: String?, selectionArgs: Array<String>?, sortOrder: String?): Cursor? = nulloverridefungetType(uri: Uri): String? = nulloverridefuninsert(uri: Uri, values: ContentValues?): Uri? = nulloverridefundelete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int = 0overridefunupdate(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<String>?): Int = 0
}

And the Common object, which I treat like an sibling of any Application class looks like this:

/**
 * Partially working like an Application class by holding the appContext which makes it accessible inside this module.
 */@SuppressLint("StaticFieldLeak")object Common {
    /**
     * App appContext
     */@Volatilelateinitvar appContext: Context

    var isStoreVersion: Boolean = falsefunsetContext(context: Context) {
        appContext = context
    }
}

As you can see I also enriched the Common object with a flag to store if the current build is a store version or not. Mainly because the BuildConfig of the app module is also not available in a module or library.

Don't forget to add the ContentProvider to the AndroidManifest of your library within the <application> tag

<provider android:name=".util.ContextProvider"
          android:authorities="${applicationId}.common.util.contextprovider"
          android:exported="false" />

Solution 5:

You can save the instance directly inside a companion object and accessing it outside without problems, I think this approach is the simplest.

IMPORTANT: change the visibility of the instance property to private to ensure no one but Application has write access.

classApp : Application() {

    overridefunonCreate() {
        super.onCreate()
        instance = this
    }

    companionobject {
        lateinitvar instance: App
            privateset
    }
}

Post a Comment for "Access Application Context In Companion Object In Kotlin"