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

简述

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的静态函数,所以可以直接这么写:
Kotlin+使用BindingAdapter注解,报错:java.lang.IllegalStateException: Required DataBindingComponent is null_第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注解的话,会产生额外的对象

你可能感兴趣的:(Jetpack,my,kotlin,java,kotlin,android,databinding,bindingadapter)