2016-07-30 11 views
0

Ich versuche, eine Anwendungsinstanz und verwenden im Konstruktor von databaseHelper zu retten, aber wenn meine Tätigkeit versucht, den databaseHelper ich die folgenden Ausnahmen zu instanziiert:Absturz App weil lateinit App-Instanz nicht initialisiert

FATAL EXCEPTION: 
main Process: com.weatherupp.weatherupp, PID: 29092 
java.lang.ExceptionInInitializerError 
at com.weatherupp.weatherupp.ui.MainActivity.onCreate(MainActivity.kt:27) 
[...] 
Caused by: kotlin.UninitializedPropertyAccessException: lateinit 
property instance has not been initialized 

die Code Ausnahme führt, ist die folgende:

MainActivity { 
override fun onCreate(savedInstanceState: Bundle?) { 
super.onCreate(savedInstanceState) 
val provider = ForecastProvider() 
[...] 
} 

ForecastProvider hat folgende Begleitobjekt:

companion object { 
    val SOURCES = listOf(ForecastServer(), ForecastDb()) 
} 

bezieht sich ForecastDb Konstruktor auf eine Instanz ForecastDbHelper, deren Konstruktor bezieht sich auf App.instance, erklärt sich wie folgt:

class App : Application() { 

    companion object { 
    lateinit var instance: App 
    } 

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

} 

Wenn ich kommentieren Sie den gesamten Code in die Datenbank Bezug genommen wird, funktioniert die App ForecastServer als Quelle verwenden Wenn ich versuche, auf die Datenbank und damit auf die App zu verweisen, löst Kotlin die UninitializedPropertyAccessException aus.

Ich habe den Code für Stunden betrachtet, kann nicht herausfinden, was ich falsch mache. Jede Hilfe ist gesegnet, danke euch allen im Voraus.

+0

, dass die onCreate App Haben Sie sich vergewissert hinzugefügt tatsächlich ausgeführt wird? Vielleicht habe ich vergessen, es dem Manifest hinzuzufügen. – FWeigl

+0

Vielen Dank! Ich kann nicht glauben, dass ich drei Stunden verloren habe und nicht bemerkt habe, dass mein Breakpoint auf App.onCreate nichts getan hat. Können Sie es als Antwort schreiben, damit ich es annehmen kann? :) –

Antwort

1

Kann nicht genau das genau feststellen, warum Ihr Ansatz nicht funktioniert, aber ich kann vorschlagen a fix:

Sie benötigen eine ForecastDb in Ihrem MainActivity. Ihre ForecastDb benötigt eine ForecastDbHelper. Ihre ForecastDbHelper benötigt die Application Instanz.

Also in Ihrem MainActivity Sie tun:

val helper = ForecastDbHelper(application as App) 
val db = ForecastDb(helper) 

und voila, Sie Ihre db fertig machen.

Dies wird als Abhängigkeitsinjektion bezeichnet und gibt Ihnen mehr Kontrolle über die Erstellung der Objekte, die ihre Abhängigkeiten selbst abrufen.

EDIT: Prüfen Sie auch, wenn Sie Ihre App Klasse, die als Application im AndroidManifest.xml wie folgt ::

<application 
    android:name=".base.App" 
    ... 
1

Ich bin kein Kotlin-Experte, aber es scheint, dass Companion-Objekte früher initialisiert werden, die Eltern Konstruktor aufrufen. Wahrscheinlich, wenn Ihre val SOURCES versuchen, es zu starten, löst Ausnahme aus, wie es versucht, unitalisierte App-Instanz zu verwenden (vor App onCreate()). Here können Sie diese ein Begleitobjekt gelesen wird initialisiert, wenn die entsprechende Klasse geladen (aufgelöst), die Semantik einer statischen Java initializer passende

+0

Gute Idee, ich habe gerade getestet und meine Anwendungen onCreate wird ausgeführt, bevor andere Klassen geladen werden, und ich denke, dieses Verhalten ist garantiert. – FWeigl

+0

Vielen Dank für Ihre Antwort und zum Aufzeigen, dass ich nicht darauf geachtet habe, aber ich denke, dass Sie die Anmerkung @JvmStatic brauchen, um sich so verhalten zu können. –