【问题标题】:Android kotlin extension errorAndroid kotlin 扩展错误
【发布时间】:2018-02-06 22:21:53
【问题描述】:

java.lang.VerifyError: .../utils/KotlinViewExtKt$animateFadeOut$1

在模拟器上运行应用程序时出现该错误PRE Lolipop (

导致问题的函数:

fun View.animateFadeOut(animDuration: Long = 250) {
    this.animate()
            .alpha(0F)
            .setDuration(animDuration)
            .setListener(object : Animator.AnimatorListener {

                override fun onAnimationRepeat(p0: Animator?) {}

                override fun onAnimationEnd(animation: Animator?, isReverse: Boolean) {
                    super.onAnimationEnd(animation, isReverse)
                    show(false)
                }

                override fun onAnimationEnd(p0: Animator?) {
                    show(false)
                }

                override fun onAnimationCancel(p0: Animator?) {
                }

                override fun onAnimationStart(animation: Animator?, isReverse: Boolean) {
                }

                override fun onAnimationStart(p0: Animator?) {
                }
            })
            .start()
}

fun View.show(show: Boolean) {
    val vis = if (show) View.VISIBLE else View.GONE
    if (visibility != vis) {
        visibility = vis
    }
}

指向.setListener 线。

在 21+ api 上完美运行。

AS 版本:3.0.1。 Kotlin 版本:1.2.21(已尝试 1.1.51)。

可能是什么原因?我的坏还是 kotlin? Multidex 已启用。

【问题讨论】:

  • 使用 AnimatorListenerAdapter 代替 AnimatorListener 而不覆盖 onAnimationEnd(Animator animation, boolean isReverse)onAnimationStart(Animator animation, boolean isReverse)

标签: java android android-studio kotlin kotlin-extension


【解决方案1】:

解决方案

基于this issuethis fix:

ViewExtension.kt

fun View.animateFadeOut(animDuration: Long = 250L) {
    this.animate()
            .alpha(0F)
            .setDuration(animDuration)
            .setListener(object : AbstractAnimatorListener() {

                override fun onAnimationEnd(animation: Animator?, isReverse: Boolean) {
                    super.onAnimationEnd(animation, isReverse)
                    show(false)
                }

                override fun onAnimationEnd(p0: Animator?) {
                    show(false)
                }
            })
            .start()
}

fun View.show(show: Boolean) {
    val vis = if (show) View.VISIBLE else View.GONE
    if (visibility != vis) {
        visibility = vis
    }
}

AbstractAnimatorListener.kt

abstract class AbstractAnimatorListener : Animator.AnimatorListener {

    override fun onAnimationRepeat(p0: Animator?) {}

    override fun onAnimationEnd(p0: Animator?) {}

    override fun onAnimationCancel(p0: Animator?) {}

    override fun onAnimationStart(p0: Animator?) {}

    override fun onAnimationEnd(animation: Animator?, isReverse: Boolean) {
        onAnimationEnd(animation)
    }

    override fun onAnimationStart(animation: Animator?, isReverse: Boolean) {
        onAnimationStart(animation)
    }
}

说明

尝试使用 Java 8 Defaults 删除 API 26 中添加的这些方法并使用替代动画:

Animator.AnimatorListener:

在 API 级别 26 中添加了 onAnimationEnd

void onAnimationEnd (Animator animation, boolean isReverse)

在 API 级别 26 中添加了 onAnimationStart

void onAnimationStart (Animator animation, boolean isReverse)

这些方法可以被覆盖,但不是必需的,以便在动画开始时获取额外的播放方向信息。

AnimatorSet:

从 Android 8.0 (API 26) 开始,AnimatorSet API 支持 反向搜索和播放。


注意:

/**
 * Skipping calling super when overriding this method results in
 * {@link #onAnimationStart(Animator)} not getting called.
 */
default void onAnimationStart(Animator animation, boolean isReverse) {
    onAnimationStart(animation);
}

我需要将this 添加到我的build.gradle 文件中进行测试

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
  kotlinOptions {
    jvmTarget = "1.8"
  }
}

或替换

super.onAnimationEnd(animation, isReverse)

通过

onAnimationEnd(animation)

为了避免错误:

在 JVM 目标 1.6 中禁止对 Java 默认方法进行超级调用。 用'-jvm-target 1.8'重新编译

并将下一行添加到我的 gradle.properties 文件 thanks to this answer

android.enableD8=true

为了避免异常:

com.android.dx.cf.code.SimException:默认或静态界面 没有使用 --min-sdk-version >= 24

的方法

现在可以编译了,刚刚启动了一个kitKat模拟器……

它可以工作,而且我的项目中也启用了 MultiDex。

对不起,我无法复制它。

或者,使用 Java 8 默认删除这两个方法,它也可以工作。


注意2:

关于 AnimatorListenerAdapter 的 Arpan 建议可行,但没有必要。

您可以删除这些方法,更改动画并创建:

object EmptyAnimatorListener : Animator.AnimatorListener {
    override fun onAnimationRepeat(p0: Animator?) {}
    override fun onAnimationEnd(p0: Animator?) {}
    override fun onAnimationCancel(p0: Animator?) {}
    override fun onAnimationStart(p0: Animator?) {}
}

并像这样使用委托:

    .setListener(object : Animator.AnimatorListener by EmptyAnimatorListener {
        override fun onAnimationStart(animation: Animator) {
            // Do something
        }

        override fun onAnimationEnd(animation: Animator) {
            // Do something
        }
    })

注3:

转载添加到扩展函数中:

E/AndroidRuntime: 致命异常: main 进程:...机器人,PID:3409 java.lang.VerifyError: com/.../ui/common/extension/android/view/ViewExtensionKt$animateFadeOut$1

  • 使用 Java Defaults 删除 Api 26 方法可以解决问题。

  • 替换调用你的 onAnimationEnd 的超级调用也可以解决它:

        override fun onAnimationEnd(animation: Animator?, isReverse: Boolean) {
            onAnimationEnd(animation)
        }
    
  • 调用 super.onAnimationStart(animation: Animator?, isReverse: Boolean) 需要 API 26:

  • 反编译 Kotlin 字节码显示这些方法无法解析:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 2018-07-03
    • 1970-01-01
    相关资源
    最近更新 更多