繁体   English   中英

在 kotlin 中访问伴随对象中的应用程序上下文

[英]Access application context in companion object in kotlin

我们如何在 Android kotlin 中访问伴随对象内的应用程序上下文? 我在抽象类中有一个伴随对象,我想访问上下文以读取共享首选项,但我无法获取上下文。

更新:我正在 Android 库中使用这些东西,而且我正在使用的类是抽象的

请看这个去链接

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()
    }
}

像这样扩展Application类

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

实际上我在Android库中工作,这个类是抽象的,所以不能使用已经建议的解决方案。 但是,我找到了这样做的方法。

  1. 在随lateinit对象中创建一个lateinit Context字段。
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);
    }
}

来自Firebase的人们发表了一篇非常酷的文章,解释了他们的SDK如何掌握上下文

基本上我的contentprovider看起来像这样:

/**
 * 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对象。 主要是因为app模块的BuildConfig在模块或库中也不可用。

不要忘记将ContentProvider添加到<application>标记内的库的AndroidManifest中

<provider android:name=".util.ContextProvider"
          android:authorities="${applicationId}.common.util.contextprovider"
          android:exported="false" />
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)   
            }
        }
    }
}

您可以将实例直接保存在伴生对象中并在外部访问它而不会出现问题,我认为这种方法是最简单的。

重要提示:将实例属性的可见性更改为private以确保除应用程序外没有其他人具有写访问权限。

class App : Application() {

    override fun onCreate() {
        super.onCreate()
        instance = this
    }

    companion object {
        lateinit var instance: App
            private set
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM