Доступ к контексту приложения в сопутствующем объекте в kotlin - PullRequest
0 голосов
/ 07 января 2019

Как мы можем получить доступ к контексту приложения внутри объекта-компаньона в Android kotlin? У меня есть объект-компаньон внутри абстрактного класса, и я хочу получить доступ к контексту для чтения общих настроек, но я не могу получить контекст.

ОБНОВЛЕНИЕ: Я работаю с этим материалом в библиотеке Android, а также класс, в котором я работаю, является абстрактным

Ответы [ 5 ]

0 голосов
/ 11 мая 2019
class Test { 

    companion object {
        lateinit var sharedPreferences: SharedPreferences

        fun init(context: Context) {
            // to prevent multiple initialization
            if (!Companion::sharedPreferences.isInitialized) {
                sharedPreferences = context.getSharedPreferences("preference_name", Context.MODE_PRIVATE)   
            }
        }
    }
}
0 голосов
/ 09 января 2019

Есть отличная статья от парней из Firebase, объясняющая , как их SDK овладевает контекстом .

В основном мой контент-провайдер выглядит так:

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

    companion object {
        private val TAG = ContextProvider::class.java.simpleName
    }

    override fun onCreate(): Boolean {
        context?.let {
            Common.setContext(it)
            return true
        }
        Logger.e(TAG, "Context injection to common failed. Context is null! Check ContextProvider registration in the Manifest!")
        return false
    }

    override fun query(uri: Uri, projection: Array<String>?, selection: String?, selectionArgs: Array<String>?, sortOrder: String?): Cursor? = null

    override fun getType(uri: Uri): String? = null

    override fun insert(uri: Uri, values: ContentValues?): Uri? = null

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int = 0

    override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<String>?): Int = 0
}

И объект Common, к которому я отношусь как к брату любого класса Application, выглядит так:

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

    var isStoreVersion: Boolean = false

    fun setContext(context: Context) {
        appContext = context
    }
}

Как вы можете видеть, я также обогатил объект Common флагом для хранения, если текущая сборка является версией хранилища или нет. Главным образом потому, что BuildConfig модуля приложения также недоступен в модуле или библиотеке.

Не забудьте добавить ContentProvider в AndroidManifest вашей библиотеки в теге <application>

<provider android:name=".util.ContextProvider"
          android:authorities="${applicationId}.common.util.contextprovider"
          android:exported="false" />
0 голосов
/ 07 января 2019

Расширяет класс приложения, как это

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

class MyApplication : Application() {

override fun onCreate() {
super.onCreate()
MyApplication.appContext = applicationContext
 }

companion object {

lateinit  var appContext: Context

}
}

тогда получите контекст вот так

     val context = MyApplication.appContext
0 голосов
/ 09 января 2019

На самом деле я работаю в библиотеке Android, и класс абстрактный, поэтому не могу согласиться с уже предложенными решениями. Однако я нашел способ сделать это.

  1. Создать lateinit Контекстное поле внутри объекта-компаньона.
abstract class MyClass {

    companion object {

        private lateinit var context: Context

        fun setContext(con: Context) {
            context=con
        }
    }
}
  1. А затем установите его после запуска приложения
public class WelcomeActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_welcome);

        MyClass.Companion.setContext(this);
    }
}
0 голосов
/ 07 января 2019

см. перейдите по ссылке

class MainApplication : Application() {

    init {
        instance = this
    }

    companion object {
        private var instance: MainApplication? = null

        fun applicationContext() : Context {
            return instance!!.applicationContext
        }
    }

    override fun onCreate() {
        super.onCreate()
        // initialize for any

        // Use ApplicationContext.
        // example: SharedPreferences etc...
        val context: Context = MainApplication.applicationContext()
    }
}
...