簡體   English   中英

Android kotlin 擴展錯誤

[英]Android kotlin extension error

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

在模擬器PRE Lolipop (<21 api)上運行應用程序時出現該錯誤

引起故障的函數:

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? 多索引已啟用。

解決方案

基於此問題此修復:

查看擴展.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 默認值刪除 API 26 中添加的這些方法並使用替代動畫:

Animator.AnimatorListener:

在 API 級別 26 中添加了 onAnimationEnd

 void onAnimationEnd (Animator animation, boolean isReverse)

在 API 級別 26 中添加了 onAnimationStart

 void onAnimationStart (Animator animation, boolean isReverse)

這些方法可以被覆蓋,但不是必需的,以在動畫開始時獲取額外的播放方向信息。

動畫師集

從 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);
}

我需要將此添加到我的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 文件中

android.enableD8=true

為避免異常:

com.android.dx.cf.code.SimException:默認或靜態接口方法,不使用 --min-sdk-version >= 24

它現在編譯,剛剛啟動一個kitKat模擬器......

它有效,並且在我的項目中也啟用了 MultiDex。

抱歉,我無法重現它。

或者,使用 Java 8 默認值刪除這兩種方法,它也可以工作。


筆記2:

Arpan 關於 AnimatorListenerAdapter 的建議會起作用,但沒有必要。

您可以刪除這些方法,更改動畫並創建:

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:致命異常:主進程:...android,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 Bytecode 顯示這些方法無法解析:

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM