迁移到新的 kotlin-parcelize
Migrate to the new kotlin-parcelize
谁能解释一下如何迁移到 new kotlin-parcelize
?
我试过了:
- 在应用 build.gradle
中将 apply plugin: 'kotlin-android-extensions'
替换为 apply plugin: 'kotlin-parcelize'
- 将
import kotlinx.android.parcel.Parcelize
替换为import kotlinx.parcelize.Parcelize
后一个导致
Class 'ParcelZonedDateTime' is not abstract and does not implement abstract member public abstract fun describeContents(): Int defined in android.os.Parcelable
例如此代码:
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()
}
}
那么,如何迁移到新的kotlin-parcelize
?
更新:
基于评论:是的,我使用的是 Kotlin 1.4.20(比 1.4.20-M2 更新)。Kyzer 是正确的,IDE ( 中的错误是not abstract and does not implement abstract member public abstract fun describeContents()) 可以而且必须被忽略。但是我在使用泛型时遇到问题:
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
sealed class MyDialogEvent {
@Parcelize
data class Confirmed<T: Parcelable>(val identity: String, val data: T) : Parcelable
}
为此生成的代码是
@kotlin.Metadata(mv = {1, 4, 1}, bv = {1, 0, 3}, k = 3)
public static final class Creator implements android.os.Parcelable.Creator<com.example.Whosebug.MyDialogEvent.Confirmed> {
public Creator() {
super();
}
@org.jetbrains.annotations.NotNull()
@java.lang.Override()
public final com.example.Whosebug.MyDialogEvent.Confirmed<T>[] newArray(int size) {
return null;
}
@org.jetbrains.annotations.NotNull()
@java.lang.Override()
public final com.example.Whosebug.MyDialogEvent.Confirmed<T> createFromParcel(@org.jetbrains.annotations.NotNull()
android.os.Parcel in) {
return null;
}
}
并且在编译期间我得到了这个错误(行号与示例代码不匹配,但您可以通过比较方法名称轻松识别匹配的行):
MyDialogEvent.java:167: error: non-static type variable T cannot be referenced from a static context
public final com.example.Whosebug.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.Whosebug.MyDialogEvent.Confirmed<T> createFromParcel(@org.jetbrains.annotations.NotNull()
更改此行:
导入 kotlinx.parcelize.Parcelize
到:
导入 kotlinx.android.parcel.Parcelize
原问题的答案:
如果您在 Android Studio 中看到此错误:
Class 'ClassName' is not abstract and does not implement abstract member public abstract fun describeContents(): Int defined in android.os.Parcelable
确保您已将 Kotlin 依赖项和 Android Studio Kotlin 插件更新到 1.4.20 或更高版本。
更新插件后,确保文件 -> 使缓存无效/重新启动。这对我有用。
进一步检查后,我认为 Parcelable
具有 Parcel 构造的泛型无法编译,因为 T class
无法根据此 reference.
泛型确定
也许枚举是最后的手段。
这是 kapt 中的一个错误,据报道 here。实际上,您发布的 java 代码是一个存根 class,由 kapt 到 运行 注释处理器在其上生成(如您所见,没有真正的实现,只有结构和注释) .因此,作为一种解决方法,您可以将带有 @Parcelize
注释的代码移动到您没有启用 kapt 的单独模块中。 kotlin-parcelize
本身不使用注释处理器生成代码,我相信它使用编译器插件直接发出 IR。
更新:问题已在 kotlin 1.5
中修复
我使用的是 Kotlin 1.4.10 版本:
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.10"
但在我的模块中,只应用
id 'kotlin-android'
id 'kotlin-android-extensions'
它对我有用。
我的模块中应用了所有插件:
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
id 'androidx.navigation.safeargs.kotlin'
}
这是我的作品,请仔细检查行序
plugins {
id 'kotlin-android'
id 'kotlin-parcelize'
id 'kotlin-kapt'
}
谁能解释一下如何迁移到 new kotlin-parcelize
?
我试过了:
- 在应用 build.gradle 中将
- 将
import kotlinx.android.parcel.Parcelize
替换为import kotlinx.parcelize.Parcelize
apply plugin: 'kotlin-android-extensions'
替换为 apply plugin: 'kotlin-parcelize'
后一个导致
Class 'ParcelZonedDateTime' is not abstract and does not implement abstract member public abstract fun describeContents(): Int defined in android.os.Parcelable
例如此代码:
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()
}
}
那么,如何迁移到新的kotlin-parcelize
?
更新:
基于评论:是的,我使用的是 Kotlin 1.4.20(比 1.4.20-M2 更新)。Kyzer 是正确的,IDE ( 中的错误是not abstract and does not implement abstract member public abstract fun describeContents()) 可以而且必须被忽略。但是我在使用泛型时遇到问题:
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
sealed class MyDialogEvent {
@Parcelize
data class Confirmed<T: Parcelable>(val identity: String, val data: T) : Parcelable
}
为此生成的代码是
@kotlin.Metadata(mv = {1, 4, 1}, bv = {1, 0, 3}, k = 3)
public static final class Creator implements android.os.Parcelable.Creator<com.example.Whosebug.MyDialogEvent.Confirmed> {
public Creator() {
super();
}
@org.jetbrains.annotations.NotNull()
@java.lang.Override()
public final com.example.Whosebug.MyDialogEvent.Confirmed<T>[] newArray(int size) {
return null;
}
@org.jetbrains.annotations.NotNull()
@java.lang.Override()
public final com.example.Whosebug.MyDialogEvent.Confirmed<T> createFromParcel(@org.jetbrains.annotations.NotNull()
android.os.Parcel in) {
return null;
}
}
并且在编译期间我得到了这个错误(行号与示例代码不匹配,但您可以通过比较方法名称轻松识别匹配的行):
MyDialogEvent.java:167: error: non-static type variable T cannot be referenced from a static context
public final com.example.Whosebug.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.Whosebug.MyDialogEvent.Confirmed<T> createFromParcel(@org.jetbrains.annotations.NotNull()
更改此行: 导入 kotlinx.parcelize.Parcelize 到: 导入 kotlinx.android.parcel.Parcelize
原问题的答案:
如果您在 Android Studio 中看到此错误:
Class 'ClassName' is not abstract and does not implement abstract member public abstract fun describeContents(): Int defined in android.os.Parcelable
确保您已将 Kotlin 依赖项和 Android Studio Kotlin 插件更新到 1.4.20 或更高版本。
进一步检查后,我认为 Parcelable
具有 Parcel 构造的泛型无法编译,因为 T class
无法根据此 reference.
也许枚举是最后的手段。
这是 kapt 中的一个错误,据报道 here。实际上,您发布的 java 代码是一个存根 class,由 kapt 到 运行 注释处理器在其上生成(如您所见,没有真正的实现,只有结构和注释) .因此,作为一种解决方法,您可以将带有 @Parcelize
注释的代码移动到您没有启用 kapt 的单独模块中。 kotlin-parcelize
本身不使用注释处理器生成代码,我相信它使用编译器插件直接发出 IR。
更新:问题已在 kotlin 1.5
中修复我使用的是 Kotlin 1.4.10 版本:
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.4.10"
但在我的模块中,只应用
id 'kotlin-android'
id 'kotlin-android-extensions'
它对我有用。
我的模块中应用了所有插件:
plugins {
id 'com.android.library'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
id 'androidx.navigation.safeargs.kotlin'
}
这是我的作品,请仔细检查行序
plugins {
id 'kotlin-android'
id 'kotlin-parcelize'
id 'kotlin-kapt'
}