Can anyone please explain how to migrate to the new kotlin-parcelize
?
I tried:
apply plugin: 'kotlin-android-extensions'
with apply plugin: 'kotlin-parcelize'
in app build.gradleimport kotlinx.android.parcel.Parcelize
with import kotlinx.parcelize.Parcelize
The latter one leads to
Class 'ParcelZonedDateTime' is not abstract and does not implement abstract member public abstract fun describeContents(): Int defined in android.os.Parcelable
on e.g. this code:
import androidx.annotation.Keep
import kotlinx.parcelize.Parcelize
import org.threeten.bp.ZonedDateTime
@Keep
@Parcelize
data class ParcelZonedDateTime(var value: ZonedDateTime?) :Parcelable {
override fun toString(): String {
return value.toString()
}
}
So, how to migrate to the new kotlin-parcelize
?
Update:
Based on comments: Yes, I am on Kotlin 1.4.20 (which is newer than 1.4.20-M2).Kyzer is right that the error in the IDE (is not abstract and does not implement abstract member public abstract fun describeContents()) can and has to be ignored. Yet I have an issue where I use Generics:
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
sealed class MyDialogEvent {
@Parcelize
data class Confirmed<T: Parcelable>(val identity: String, val data: T) : Parcelable
}
The generated code for this is
@kotlin.Metadata(mv = {1, 4, 1}, bv = {1, 0, 3}, k = 3)
public static final class Creator implements android.os.Parcelable.Creator<com.example.stackoverflow.MyDialogEvent.Confirmed> {
public Creator() {
super();
}
@org.jetbrains.annotations.NotNull()
@java.lang.Override()
public final com.example.stackoverflow.MyDialogEvent.Confirmed<T>[] newArray(int size) {
return null;
}
@org.jetbrains.annotations.NotNull()
@java.lang.Override()
public final com.example.stackoverflow.MyDialogEvent.Confirmed<T> createFromParcel(@org.jetbrains.annotations.NotNull()
android.os.Parcel in) {
return null;
}
}
and during compilation I get this error for it (line numbers won't match the sample code, but you can easily identify the matching lines by comparing the method names):
MyDialogEvent.java:167: error: non-static type variable T cannot be referenced from a static context
public final com.example.stackoverflow.MyDialogEvent.Confirmed<T>[] newArray(int size) {
MyDialogEvent.java:173: error: non-static type variable T cannot be referenced from a static context
public final com.example.stackoverflow.MyDialogEvent.Confirmed<T> createFromParcel(@org.jetbrains.annotations.NotNull()
Kotlin Android Extensions is deprecated, which means that using Kotlin synthetics for view binding is no longer supported.
Just add the @Parcelize annotation to a class implementing the Parcelable interface and the Parcelable implementation will be generated automatically. This is the same example as in the previous article, in just 2 lines of code. The class can be a data class but it's optional.
There are 3 ways you can make your class Parcelable: Implementing the Parcelable interface and defining the serialization yourself (The traditional way) Using Android Studio plugins, like Android Parcelable code generator. Using annotation-based libraries, like Parceler.
If you want to give it a try you need to install the Kotlin EAP Plugin for IntelliJ IDEA or Android Studio Select Tools → Kotlin → Configure Kotlin Plugin Updates. Click Check again. Here is what you should do to migrate from kotlin-android-extensions Kotlin plugin to ViewBinding and kotlin-parcelize plugin
Don’t forget that Parcelize feature in Kotlin is part of the kotlin-android-extensions compiler plugin, so removing the plugin will endup making all your Parcelable classes not compiling if they depend on the Parcelize annotation. JetBrains extracted the Parcelize from Kotlin Android Extensions to a new plugin, kotlin-parcelize
On Android, Parcelable is an interface that a class can implement to be passed within an Intent from an Activity to another one, this way, transporting data from one Activity to another one. But with thanks to KOTLIN, we do not need to override these methods. We can directly use parcelize to handle this with minimal code.
Add binding object in your activities and fragments and use it to set the content view and access views from your xml files. If you are using Parcelize annotation, then add the new kotlin-parcelize plugin into your modules build.gradle files and change the import statements as mentioned above.
That's a bug in kapt and it's reported here. Actually the java code you posted is a stub class which generated by kapt to run annotation processors on it (as you can see, there is no real implementation, just the structure and annotations). So as a workaround you can move the code with @Parcelize
annotations to a separate module where you don't have kapt enabled. kotlin-parcelize
itself does not use annotation processors to generate code, it uses a compiler plugin to emit the IR directly I believe.
Update: the issue is fixed in kotlin 1.5
After further checking, I think Parcelable
generic type with Parcel constructing fails to compile because T class
can not be determined generically based from this reference.
Perhaps an enum could be the last resort.
This is work for me, please check the order of lines carefully
plugins {
id 'kotlin-android'
id 'kotlin-parcelize'
id 'kotlin-kapt'
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With