为什么我得到错误java.lang.IllegalStateException:instance not initialized?

时间:2017-11-13 09:31:15

标签: android kotlin

我收到错误

  

java.lang.IllegalStateException:instance not initialized

您可以在https://www.dropbox.com/s/gxeok1fyttsl54u/MyMirror.zip?dl=0

进行测试

似乎UIApp中的代码operator fun getValue(thisRef: Any?, property: KProperty<*>)...导致错误。

但代码来自示例代码,我几乎不会更改,您可以在https://github.com/antoniolg/Kotlin-for-Android-Developers/blob/master/app/src/main/java/com/antonioleiva/weatherapp/ui/App.kt看到源代码

https://github.com/antoniolg/Kotlin-for-Android-Developers/blob/master/app/src/main/java/com/antonioleiva/weatherapp/extensions/DelegatesExtensions.kt

为什么?

java.lang.RuntimeException: Unable to start activity ComponentInfo{info.dodata.mirror/ui.UIMain}: java.lang.IllegalStateException: instance not initialized
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2107)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2132)
at android.app.ActivityThread.access$700(ActivityThread.java:140)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1238)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4918)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.IllegalStateException: instance not initialized
at ui.UIApp$NotNullSingleValueVar.getValue(UIApp.kt:23)
at ui.UIApp$Companion.getInstance(UIApp.kt)
at dal.DBSettingHelper.<init>(DBSettingHelper.kt:9)
at ui.UIMain.onCreate(UIMain.kt:14)
at android.app.Activity.performCreate(Activity.java:5185)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2071)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2132)?
at android.app.ActivityThread.access$700(ActivityThread.java:140)?
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1238)?
at android.os.Handler.dispatchMessage(Handler.java:99)?
at android.os.Looper.loop(Looper.java:137)?
at android.app.ActivityThread.main(ActivityThread.java:4918)?
at java.lang.reflect.Method.invokeNative(Native Method)?
at java.lang.reflect.Method.invoke(Method.java:511)?
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)?
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)?
at dalvik.system.NativeStart.main(Native Method)?

UIMain

package ui
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import dal.DBSettingHelper
import info.dodata.mirror.R


class UIMain : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.layout_main)
        var ss= DBSettingHelper();
    }

}

DBSettingHelper

package dal

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import org.jetbrains.anko.db.*
import ui.UIApp

object DBSettingTable {
    val TableNAME = "SettingTable"

    val _ID = "_id"
    val Name = "name"
    val CreatedDate = "createdDate"
    val Description="description"
}


class DBSettingHelper(mContext: Context = UIApp.instance) : ManagedSQLiteOpenHelper(
        mContext,
        DB_NAME,
        null,
        DB_VERSION) {

    companion object {
        val DB_NAME = "setting.db"
        val DB_VERSION = 1
        val instance by lazy { DBSettingHelper() }
    }

    override fun onCreate(db: SQLiteDatabase) {
        db.createTable( DBSettingTable.TableNAME , true,
                DBSettingTable._ID to INTEGER + PRIMARY_KEY,
                DBSettingTable.Name to TEXT,
                DBSettingTable.CreatedDate to INTEGER,
                DBSettingTable.Description to TEXT
        )
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        db.dropTable(DBSettingTable.TableNAME, true)
        onCreate(db)
    }

}

了UiApp

package ui

import android.app.Application
import kotlin.reflect.KProperty

class UIApp : Application() {

    companion object {
        var instance: UIApp by NotNullSingleValueVar()
    }

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

    class NotNullSingleValueVar<T> {

        private var value: T? = null

        operator fun getValue(thisRef: Any?, property: KProperty<*>): T =
                value ?: throw IllegalStateException("${property.name} not initialized")

        operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
            this.value = if (this.value == null) value
            else throw IllegalStateException("${property.name} already initialized")
        }
    }

1 个答案:

答案 0 :(得分:3)

永远不会调用UIApp类中的

onCreate 函数,因此永远不会初始化UIApp的实例。发生这种情况是因为您没有将UIApp类添加到AndroidManifest,因此您的应用程序没有意识到您在项目中拥有自定义Application类。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="info.dodata.mirror">

    <application
        <!--Add line bellow to your manifest file and app will work just fine-->
        android:name="ui.UIApp"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">


        <activity android:name="ui.UIMain">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>