butterknife: Quoting Butter Knife 8.8.1 in the library, using BindView in the app module, but the view appears NullPointerException

I used a butterknife 8.8.1 in AndroidStudio3.0。 My project gradle:

buildscript {
    repositories {
        jcenter()
        ......
        mavenCentral()
        maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'
        classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0-SNAPSHOT'
    }
}
allprojects {
    repositories {
        jcenter()
        ......
        maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
        google()
    }
}

In my app module gradle:

......
apply plugin: 'com.jakewharton.butterknife'

In my Library module gradle:

apply plugin: 'com.android.library'
dependencies {
    ......
    compile "com.jakewharton:butterknife:${butterknifeSdkVersion}"
    annotationProcessor "com.jakewharton:butterknife-compiler:${butterknifeSdkVersion}"
}

In my app module activity binding View, @ BindView (R.id.xx) and @BindView (R2.id.xx) have tried, but still NullPointerException.Why is that?


My English is relatively poor, the above text from the Google translation, grammar unreasonable please understand

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Comments: 34 (1 by maintainers)

Most upvoted comments

must add annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' in app module to solve this problem.

@qinxianyuzou 这个不是 bug ,因为 butterknife 的工作机制是:利用 annotationProcessor 来生成 XXX_ViewBinding 类的,对应的 XXX 里面的 View 的初始化是在 XXX_ViewBinding 内完成的。 而 annotationProcessor 是以 module 为单位工作的,所以解决方法很简单,在 app module 内引用 annotationProcessor 而在 library 内引用 butterknife 即可解决。


  @Nullable @CheckResult @UiThread
  private static Constructor<? extends Unbinder> findBindingConstructorForClass(Class<?> cls) {
    Constructor<? extends Unbinder> bindingCtor = BINDINGS.get(cls);
    if (bindingCtor != null) {
      if (debug) Log.d(TAG, "HIT: Cached in binding map.");
      return bindingCtor;
    }
    String clsName = cls.getName();
    if (clsName.startsWith("android.") || clsName.startsWith("java.")) {
      if (debug) Log.d(TAG, "MISS: Reached framework class. Abandoning search.");
      return null;
    }
    try {
      Class<?> bindingClass = Class.forName(clsName + "_ViewBinding");
      //noinspection unchecked
      bindingCtor = (Constructor<? extends Unbinder>) bindingClass.getConstructor(cls, View.class);
      if (debug) Log.d(TAG, "HIT: Loaded binding class and constructor.");
    } catch (ClassNotFoundException e) {
      if (debug) Log.d(TAG, "Not found. Trying superclass " + cls.getSuperclass().getName());
      bindingCtor = findBindingConstructorForClass(cls.getSuperclass());
    } catch (NoSuchMethodException e) {
      throw new RuntimeException("Unable to find binding constructor for " + clsName, e);
    }
    BINDINGS.put(cls, bindingCtor);
    return bindingCtor;
  }

个人见解,轻喷

@kassim Thank you kassim I just used “kapt” a minute ago and solved the problem. have a good day~!

Thank you @gmm932 Your suggestion works (probably missed that part from README file)

App level configuration:

dependencies {
    implementation 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
}

Project level configuration:

buildscript {
     dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
        classpath 'com.jakewharton:butterknife-gradle-plugin:8.8.1'
  }
}

@qinxianyuzou 大神,问题解决没?我无意间看到其他大神在library里面引用butterknife,首先在project的gradle文件里面的buildscript下面用butterknife作者提供的插件dependencies { classpath ‘com.jakewharton:butterknife-gradle-plugin:8.8.1’ },然后在library的module的gradle里面添加上这两个插件: apply plugin: ‘com.android.library’ apply plugin: ‘com.jakewharton.butterknife’ ,最后在所有@BindView的地方用R2.id.替换掉R.id.,这样就不会空指针了,好像butterknife的readme里面也是这样介绍的,可能大神你没太注意,希望可以帮助到你和其他遇到问题的大神们,好像说是android资源查找的机制导致的,所以jakewharton大神自己提供了一个gradle插件com.jakewharton:butterknife-gradle-plugin:***就是解决这个问题的

did anyone find a solution? I am facing the same problem in gradle:3.0.0

在defaultConfig中加入 javaCompileOptions { annotationProcessorOptions { includeCompileClasspath true } } 就可以继续用7.0.1啦,当前最新版本的问题还请 @JakeWharton 大神解决下