Kotlin+使用BindingAdapter注解,报错:java.lang.IllegalStateException: Required DataBindingComponent is null

12 篇文章 0 订阅
11 篇文章 0 订阅

简述

java.lang.IllegalStateException: Required DataBindingComponent is null in class ActivityDatabindingBaseBindingImpl. A BindingAdapter in com.zxf.jetpackrelated.databinding.simpleUse.ImageViewAdapter is not static and requires an object to use, retrieved from the DataBindingComponent. If you don’t use an inflation method taking a DataBindingComponent, use DataBindingUtil.setDefaultComponent or make all BindingAdapter methods static.

简单理解一下,用BindingAdapter修饰的方法不是静态方法。但是需要是静态方法。

问题原因分析

猜测,你应该是以下两种写法之一😂

  1. class ImageViewAdapter{
        companion object{
            @BindingAdapter("image")
            fun setImage(imageView: ImageView, imageUrl: String?) {
                if (imageUrl.isNotNullOrEmpty()) {
                    Glide.with(imageView)
                        .load(imageUrl)
                        .into(imageView)
                } else {
                    imageView.setBackgroundColor(Color.BLUE)
                }
            }
        }
    }
    
  2. object ImageViewAdapter{
        @BindingAdapter("image")
        fun setImage(imageView: ImageView, imageUrl: String?) {
            if (imageUrl.isNotNullOrEmpty()) {
                Glide.with(imageView)
                    .load(imageUrl)
                    .into(imageView)
            } else {
                imageView.setBackgroundColor(Color.BLUE)
            }
        }
    }
    

虽然以上两种写法在使用上和静态方法差不多,但在运行时它们任然是真正对象的成员实例;可以简单看一下第一种写法生成的java代码的样子

public final class ImageViewAdapter {
   @NotNull
   public static final ImageViewAdapter.Companion Companion = new ImageViewAdapter.Companion((DefaultConstructorMarker)null);
   public static final class Companion {
      @BindingAdapter({"image"})
      public final void setImage(@NotNull ImageView imageView, @Nullable String imageUrl) {
         Intrinsics.checkNotNullParameter(imageView, "imageView");
         if (ExtensionUtilsKt.isNotNullOrEmpty((CharSequence)imageUrl)) {
            Intrinsics.checkNotNullExpressionValue(Glide.with((View)imageView).load(imageUrl).into(imageView), "Glide.with(imageView)\n  …         .into(imageView)");
         } else {
            imageView.setBackgroundColor(-16776961);
         }
      }
   }
}

其实内部还是非静态的方法调用,只是通过静态字段的初始化,保证了其单例的特性。object和 这个类似,大家可以自行查看编译后的java代码。

解决

如果非要使用以上的方式,那么需要增加@JvmStatic注解,这样kotlin在编译为java代码的时候,可以为其生成对应的静态方法。

  1. class ImageViewAdapter{
        companion object{
            @BindingAdapter("image")
            @JvmStatic
            fun setImage(imageView: ImageView, imageUrl: String?) {
                if (imageUrl.isNotNullOrEmpty()) {
                    Glide.with(imageView)
                        .load(imageUrl)
                        .into(imageView)
                } else {
                    imageView.setBackgroundColor(Color.BLUE)
                }
            }
        }
    }
    
  2. object ImageViewAdapter{
        @BindingAdapter("image")
        @JvmStatic
        fun setImage(imageView: ImageView, imageUrl: String?) {
            if (imageUrl.isNotNullOrEmpty()) {
                Glide.with(imageView)
                    .load(imageUrl)
                    .into(imageView)
            } else {
                imageView.setBackgroundColor(Color.BLUE)
            }
        }
    }
    

简单看一下反编译之后的代码,kotlin生成了对应的静态方法,调用了产生的伴生对象

   public static final void setImage(@NotNull ImageView imageView, @Nullable String imageUrl) {
      Companion.setImage(imageView, imageUrl);
   }

那有没有不需要增加注解就直接是静态方法的办法呢?当然有,在kotlin里面顶级函数,就对应java的静态函数,所以可以直接这么写:
![在这里插入图片描述](https://img-blog.csdnimg.cn/dfff6534242c4dbb80f8c082f5735de1.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAcHVtcGtpbueahOeOhOWtpg==,size_14,color_FFFFFF,t_70,g_se,x_1
直接使用顶级函数就可以了,可以看一下,编译后的java代码:

public final class CustomBindingAdapterKt {
   @BindingAdapter({"image"})
   public static final void setImage(@NotNull ImageView imageView, @Nullable String imageUrl) {
      Intrinsics.checkNotNullParameter(imageView, "imageView");
      if (ExtensionUtilsKt.isNotNullOrEmpty((CharSequence)imageUrl)) {
         Intrinsics.checkNotNullExpressionValue(Glide.with((View)imageView).load(imageUrl).into(imageView), "Glide.with(imageView)\n  …         .into(imageView)");
      } else {
         imageView.setBackgroundColor(-16776961);
      }

   }
}

对应java的类名为文件名+kt,对应的方法为static final修饰的方法。
推荐呢还是直接使用顶级函数方便一点。如果使用伴生对象+JvmStatic注解的话,会产生额外的对象

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pumpkin的玄学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值