2016-05-23 39 views
15

所以在android中,我想讓我的應用程序類是一個單身人士。Kotlin SingleTon應用程序類

使其像這樣:

object MyApplication: Application(){} 

將無法​​正常工作。以下誤差修改是在運行時拋出:

java.lang.IllegalAccessException: private com....is not accessible from class android.app.Instrumentation. 

這樣做也是不可能的:

class MyApp: Application() { 

    private val instance_: MyApp 

    init{ 
     instance_ = this 
    } 

    override fun onCreate() { 
     super.onCreate() 
     if (BuildConfig.DEBUG) { 
      Timber.plant(Timber.DebugTree()); 
     } 
    } 

    companion object{ 
     fun getInstance() = instance_   
    } 
} 

那麼,如何才能讓我的應用程序類無處不在我的應用程序的實例,想用MyApp.instance()代替(applicationContext as MyApp)

另外一個解釋,爲什麼我想要這樣的:我有我的應用程序中的類,例如,一個SharedPreference Singleton用上下文初始化,並且作爲其單例,不能有參數。

回答

15

如果你想使用它來訪問你有的一些靜態屬性:你將只有一個你的應用程序的實例,所以只需使用你給這個類的名字。不要擔心它不是一個真正的單身人士,你可以用同樣的方式。

例子:

class MyApp : Application() { 

    companion object { 
     const val CONSTANT = 12 
     lateinit var typeface: Typeface 
    } 

    override fun onCreate() { 
     super.onCreate() 
     typeface = Typeface.createFromAsset(assets, "fonts/myFont.ttf") 
    } 

} 

然後你就可以在你的應用程序在任何地方使用MyApp.CONSTANTMyApp.typeface

-

如果你想要的是使用它作爲一個應用程序上下文您可以創建上下文的擴展屬性:

val Context.myApp: MyApp 
     get() = applicationContext as MyApp 

然後你就可以使用myApp得到的應用程序上下文在任何地方。

+0

這看起來不錯@nitrico,但我無法獲得'val Context.myApp:MyApp get()= applicationContext作爲MyApp的部分工作。你可以進一步瞭解更多細節嗎?這條線路需要去哪裏以及如何在另一個班級訪問? – shredder

2

您不能這樣做,因爲Android使用其無參數構造函數創建Application實例。

您想解決的問題可以通過DI輕鬆解決。只需使用注入器創建實例,以便可以將Context作爲依賴注入到對象中。

+0

你我一直知道這個解決方案,但希望有另一種方式。感謝的人 –

29

你可以做同樣的事情你會用Java做,即將Application實例放在一個靜態字段中。 Kotlin沒有靜態字段,但對象中的屬性是靜態可訪問的。

class MyApp: Application() { 

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

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

然後,您可以通過MyApp.instance訪問該屬性。