首页 > 解决方案 > 指定为非 null 的参数为 null - 在 Kotlin 中加载图像

问题描述

我正在使用 Picassos Target 从 Internet 加载图像并从中生成调色板。当图像不再存在时,我会在 Logcat 中出现以下错误并崩溃:

 java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter placeHolderDrawable
        at .ActivityThread.performLaunchActivity(ActivityThread.java:3260)
        at .ActivityThread.handleLaunchActivity(ActivityThread.java:3396)
        at .servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at .servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at .servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at .ActivityThread$H.handleMessage(ActivityThread.java:2009)
        at .Handler.dispatchMessage(Handler.java:107)
        at .Looper.loop(Looper.java:214)
        at .ActivityThread.main(ActivityThread.java:7319)
        at .reflect.Method.invoke(Native Method)
        at .os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at .os.ZygoteInit.main(ZygoteInit.java:934)
     Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter placeHolderDrawable
        at .LoadImage$onCreate$1.onPrepareLoad(Unknown Source:2)
        at com.squareup.picasso.RequestCreator.into(RequestCreator.java:559)
        at .LoadImage.onCreate(LoadImage.kt:154)
        **at .LoadImage.onCreate(LoadImage.kt:154)**

好的,我了解发生了什么 - 毕加索加载图像,图像为空,因此应用程序崩溃。但是我怎样才能用一行代码来处理这个问题呢?

这是发生问题的部分,我为您标记了第 154 行:

    Picasso.get()
            .load(eventimgurl)
            **.into(object : com.squareup.picasso.Target {**
                override fun onBitmapLoaded(bitmap: Bitmap, from: Picasso.LoadedFrom) {
                    assert(iconImg != null)
                    iconImg!!.setImageBitmap(bitmap)
                    Palette.from(bitmap)
                            .generate(Palette.PaletteAsyncListener { palette ->
                                val dividerswatch_dom = palette!!.dominantSwatch
                                val dividerswatch_sub = palette.lightVibrantSwatch

                                if (dividerswatch_dom == null || dividerswatch_sub == null) {

                                    return@PaletteAsyncListener
                                }


                                val gd = GradientDrawable(
                                        GradientDrawable.Orientation.LEFT_RIGHT,
                                        intArrayOf(dividerswatch_dom.rgb, dividerswatch_sub.rgb))
                                gd.cornerRadius = 0f
                                gd.gradientType = GradientDrawable.RADIAL_GRADIENT
                                gd.gradientRadius = 700.0f


                                eventdividerheader.background = gd
                                eventdividerdjstart.background = gd
                                eventdivider_detail_top.background = gd
                                eventdivider_detail_bottom.background = gd

                            })
                }

                override fun onBitmapFailed(e: Exception, errorDrawable: Drawable) {

                }

                override fun onPrepareLoad(placeHolderDrawable: Drawable) {

                }
            })

标签: androidkotlinpicassonullableillegalargumentexception

解决方案


实际上,问题在于库代码与 Kotlin 不完全兼容。或者实际上,更多的是关于您使用的 IDE,而不是库。

为什么?

interface Target {
    void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from)
    void onBitmapFailed(Exception e, Drawable errorDrawable)
    void onPrepareLoad(Drawable placeHolderDrawable)
}

上面的接口将是 Target 的 java 接口。由于在 Kotlin 代码中使用 this 没有空注释可能非常棘手,因为我们不知道placeHolderDrawable(和其他变量)的类型是否可以为空。

所以,这个接口的 kotlin 实现如下:

object : Target {
    // ...
    override fun onPrepareLoad(placeHolderDrawable: Drawable) {
    }
}

或者...

object : Target {
    // ...
    override fun onPrepareLoad(placeHolderDrawable: Drawable?) {
    }
}

我们在这里。当 Kotlin 编译为 Java 字节码时,它会not-null checks添加not-null types

kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull(param)

因此,要使您的代码正常工作...只需更改DrawableDrawable?. 那么,就不会有Intrinsics电话,也不会有例外。

因此,即使您的方法是空的,编译器也会在方法Intrinsics的开头添加对所有非空参数的检查。随意反编译您的代码并在空方法中找到这些调用:)

结论 问题在于nullability annotationsIDE 没有正确生成代码,因为类型被转换为非空类型而不是可空类型。


推荐阅读