简体   繁体   English

如何在 Android 中使用 kotlin 枚举修复“java.lang.InstantiationError”

[英]How to fix 'java.lang.InstantiationError' with kotlin enum in Android

I'm trying to start a new kotlin activity from a legacy java activity in Android, and need to pass an enum (defined in kotlin) as an intent extra.我正在尝试从 Android 中的旧 Java 活动开始一个新的 kotlin 活动,并且需要传递一个枚举(在 kotlin 中定义)作为额外的意图。 From the first (java) activity, I can see the intent extra, but from the second (kotlin) activity, the app crashes because the intent extra is gone.从第一个 (java) 活动中,我可以看到额外的意图,但从第二个 (kotlin) 活动中,应用程序崩溃了,因为额外的意图消失了。 Is there a way to pass the enum directly, or do I have to revert to passing the enum's name or ordinal?有没有办法直接传递枚举,或者我必须恢复传递枚举的名称或序数?

Please note that there is no error if the enum class does not contain any abstract functions of its own (in this case, getTitle() ).请注意,如果枚举类不包含其自身的任何抽象函数(在本例中为getTitle() ),则不会出现错误。 However, I need to keep these functions.但是,我需要保留这些功能。

MainActivity.java主活动.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                IntentExtension.putParcelableExtra(intent, "test", TestEnum.TWO);
                startActivityForResult(intent, 42);
            }
        });
    }
}

SecondActivity.kt第二个活动.kt

@Parcelize
enum class TestEnum : Parcelable {
    ONE {
        override fun getTitle(): String = "Title One!"
    },

    TWO {
        override fun getTitle(): String = "Title Two!"
    };

    abstract fun getTitle(): String
}

class SecondActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)
        val extra = intent.getParcelableExtra<TestEnum>("test") // crash here
        welcomeText.text = getString(R.string.message, extra.name)
    }
}

IntentExtension.kt意图扩展.kt

@file:JvmName("IntentExtension")

fun Intent.putParcelableExtra(key: String, value: Parcelable) {
    this.putExtra(key, value)
}

Error Log错误日志

    java.lang.InstantiationError: com.example.myapplication.TestEnum
        at com.example.myapplication.TestEnum$Creator.createFromParcel(Unknown Source:5)
        at android.os.Parcel.readParcelable(Parcel.java:2782)
        at android.os.Parcel.readValue(Parcel.java:2676)
        at android.os.Parcel.readArrayMapInternal(Parcel.java:3043)
        at android.os.BaseBundle.unparcel(BaseBundle.java:257)
        at android.os.Bundle.getParcelable(Bundle.java:888)
        at android.content.Intent.getParcelableExtra(Intent.java:7075)
        at com.example.myapplication.SecondActivity.onCreate(SecondActivity.kt:27)
        at android.app.Activity.performCreate(Activity.java:6975)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

It seems that kotlin annotation processor can't generate right code for enum parcelization.似乎 kotlin 注释处理器无法为枚举分块生成正确的代码。 Write your own code like this:像这样编写自己的代码:

enum class TestEnum : Parcelable {
    ONE {
        override fun getTitle(): String = "Title One!"
    },

    TWO {
        override fun getTitle(): String = "Title Two!"
    };

    abstract fun getTitle(): String

    override fun describeContents(): Int {
        return 0
    }

    override fun writeToParcel(dest: Parcel?, flags: Int) {
        dest!!.writeInt(ordinal)
    }

    companion object CREATOR : Parcelable.Creator<TestEnum> {
        override fun createFromParcel(parcel: Parcel): TestEnum {
            return values()[parcel.readInt()]
        }

        override fun newArray(size: Int): Array<TestEnum?> {
            return newArray(size)
        }
    }
}

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

相关问题 在耶拿运行sparql查询时出现java.lang.InstantiationError - java.lang.InstantiationError while running sparql query in jena 使用Objenesis创建静态内部类的实例时出现java.lang.InstantiationError - java.lang.InstantiationError when creating instance of static inner class with Objenesis 如何修复 java.lang.ClassNotFoundException: kotlin.String - how to fix java.lang.ClassNotFoundException: kotlin.String 如何在Android中修复java.lang.OutOfMemoryError - How to fix java.lang.OutOfMemoryError in Android Kotlin 中的枚举类对于 Android 来说是否像 Java 一样“昂贵”? - Are Enum classes in Kotlin "expensive" for Android as in Java? 如何在Android Studio上修复java.lang.RuntimeException? - How to fix java.lang.RuntimeException on Android Studio? 如何修复java.lang.NullPointerException(android)? - How do I fix my java.lang.NullPointerException (android)? 如何修复Android 4.2.2中的java.lang.SecurityException - How to fix java.lang.SecurityException Android 4.2.2 如何修复 NullPointerException “org.apache.commons.lang3.SystemUtils.JAVA_SPECIFICATION_VERSION_AS_ENUM”是 null? - How to fix NullPointerException “org.apache.commons.lang3.SystemUtils.JAVA_SPECIFICATION_VERSION_AS_ENUM” is null? 如何从 Kotlin 中的 Java 枚举中获取名称 - How to get name from Java enum in Kotlin
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM