JakeWharton / butterknife

Bind Android views and callbacks to fields and methods.
http://jakewharton.github.io/butterknife/
Apache License 2.0
25.56k stars 4.6k forks source link

Missing resource ID #974

Closed yperess closed 5 years ago

yperess commented 7 years ago

I'm running:

My project has an app module an a library module, in the app module I've included:

dependencies {
    ...
    compile "com.jakewharton:butterknife:$butterknife_version"
    kapt "com.jakewharton:butterknife-compiler:$butterknife_version"
}

In the library module I have:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath "com.jakewharton:butterknife-gradle-plugin:$butterknife_version"
    }
}

apply plugin: 'com.android.library'
apply plugin: 'com.jakewharton.butterknife'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
android {
    ...
}
dependencies {
    ...
    compile "com.jakewharton:butterknife:$butterknife_version"
    kapt "com.jakewharton:butterknife-compiler:$butterknife_version"
}

My library code includes a custom view called CameraControlView with the following:

@OnClick(R2.id.switch_camera)
fun switchCamera() {
}

The generated CameraControlView_ViewBinding.java has the following offending line:

view = Utils.findRequiredView(source, 2131493059, "method 'switchCamera'");

R2.id.switch_camera is 0x7f0c00c3 (2131493059) R.id.switch_camera is 0x7f0c00c3 in library R.id.switch_camera is 0x7f100186 in app

Am I configuring butterknife wrong for the library or is this a bug?

JakeWharton commented 7 years ago

I doubt Butter Knife works in Kotlin libraries. That should emit an R reference not a raw integer.

On Sat, Jun 10, 2017, 2:12 PM yperess notifications@github.com wrote:

I'm running:

  • Android Studio 2.3.3
  • Kotlin 1.1.2-3
  • Butterknife 8.6.0

My project has an app module an a library module, in the app module I've included:

dependencies { ... compile "com.jakewharton:butterknife:$butterknife_version" kapt "com.jakewharton:butterknife-compiler:$butterknife_version" }

In the library module I have:

buildscript { repositories { jcenter() } dependencies { classpath "com.jakewharton:butterknife-gradle-plugin:$butterknife_version" } }

apply plugin: 'com.android.library' apply plugin: 'com.jakewharton.butterknife' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' android { ... } dependencies { ... compile "com.jakewharton:butterknife:$butterknife_version" kapt "com.jakewharton:butterknife-compiler:$butterknife_version" }

My library code includes a custom view called CameraControlView with the following:

@OnClick(R2.id.switch_camera) fun switchCamera() { }

The generated CameraControlView_ViewBinding.java has the following offending line:

view = Utils.findRequiredView(source, 2131493059, "method 'switchCamera'");

R2.id.switch_camera is 0x7f0c00c3 (2131493059) R.id.switch_camera is 0x7f0c00c3 in library R.id.switch_camera is 0x7f100186 in app

Am I configuring butterknife wrong for the library or is this a bug?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/JakeWharton/butterknife/issues/974, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEVRi2PQdhCxZI9AGKWppaFzYugLpks5sCtylgaJpZM4N2Lt3 .

yperess commented 7 years ago

Do you mean that R2 should contain something like switch_camera = com.example.R.id.switch_camera?

The generated R2 contains:

    @IdRes
    public static final int switch_camera = 0x7f0c00c3;

Library R contains:

        public static int switch_camera=0x7f0c00c3;

App R contains:

        public static final int switch_camera=0x7f100186;
JakeWharton commented 7 years ago

No, the generated view binder should emit an R reference and not a raw integer. R2 should have integers.

On Sat, Jun 10, 2017, 2:28 PM yperess notifications@github.com wrote:

Do you mean that R2 should contain something like switch_camera = com.example.R.id.switch_camera?

The generated R2 contains:

@IdRes
public static final int switch_camera = 0x7f0c00c3;

Library R contains:

    public static int switch_camera=0x7f0c00c3;

App R contains:

    public static final int switch_camera=0x7f100186;

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/JakeWharton/butterknife/issues/974#issuecomment-307582304, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEa2WqVlUQFJrkbf4eN51xe6qAunuks5sCuBYgaJpZM4N2Lt3 .

yperess commented 7 years ago

I see, any more info I can provide to debug?

On Sat, Jun 10, 2017, 2:36 PM Jake Wharton notifications@github.com wrote:

No, the generated view binder should emit an R reference and not a raw integer. R2 should have integers.

On Sat, Jun 10, 2017, 2:28 PM yperess notifications@github.com wrote:

Do you mean that R2 should contain something like switch_camera = com.example.R.id.switch_camera?

The generated R2 contains:

@IdRes public static final int switch_camera = 0x7f0c00c3;

Library R contains:

public static int switch_camera=0x7f0c00c3;

App R contains:

public static final int switch_camera=0x7f100186;

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub < https://github.com/JakeWharton/butterknife/issues/974#issuecomment-307582304 , or mute the thread < https://github.com/notifications/unsubscribe-auth/AAEEEa2WqVlUQFJrkbf4eN51xe6qAunuks5sCuBYgaJpZM4N2Lt3

.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/JakeWharton/butterknife/issues/974#issuecomment-307582702, or mute the thread https://github.com/notifications/unsubscribe-auth/AJF_-jyrG-n5fPbVEtieVC2dv8aEdlUhks5sCuI7gaJpZM4N2Lt3 .

JakeWharton commented 7 years ago

I'm pretty sure this flat out can't work in kapt because we use a javac-internal API currently to look up the R class. I'd have to reach out to the Kotlin people about it.

On Sat, Jun 10, 2017, 3:05 PM yperess notifications@github.com wrote:

I see, any more info I can provide to debug?

On Sat, Jun 10, 2017, 2:36 PM Jake Wharton notifications@github.com wrote:

No, the generated view binder should emit an R reference and not a raw integer. R2 should have integers.

On Sat, Jun 10, 2017, 2:28 PM yperess notifications@github.com wrote:

Do you mean that R2 should contain something like switch_camera = com.example.R.id.switch_camera?

The generated R2 contains:

@IdRes public static final int switch_camera = 0x7f0c00c3;

Library R contains:

public static int switch_camera=0x7f0c00c3;

App R contains:

public static final int switch_camera=0x7f100186;

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub <

https://github.com/JakeWharton/butterknife/issues/974#issuecomment-307582304

, or mute the thread <

https://github.com/notifications/unsubscribe-auth/AAEEEa2WqVlUQFJrkbf4eN51xe6qAunuks5sCuBYgaJpZM4N2Lt3

.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub < https://github.com/JakeWharton/butterknife/issues/974#issuecomment-307582702 , or mute the thread < https://github.com/notifications/unsubscribe-auth/AJF_-jyrG-n5fPbVEtieVC2dv8aEdlUhks5sCuI7gaJpZM4N2Lt3

.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/JakeWharton/butterknife/issues/974#issuecomment-307584267, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEau8TfCy_YaeDLxoYly5uJJRAsm1ks5sCujpgaJpZM4N2Lt3 .

yperess commented 7 years ago

https://github.com/JetBrains/kotlin-examples/tree/master/gradle/android-butterknife

On Sat, Jun 10, 2017, 3:39 PM Jake Wharton notifications@github.com wrote:

I'm pretty sure this flat out can't work in kapt because we use a javac-internal API currently to look up the R class. I'd have to reach out to the Kotlin people about it.

On Sat, Jun 10, 2017, 3:05 PM yperess notifications@github.com wrote:

I see, any more info I can provide to debug?

On Sat, Jun 10, 2017, 2:36 PM Jake Wharton notifications@github.com wrote:

No, the generated view binder should emit an R reference and not a raw integer. R2 should have integers.

On Sat, Jun 10, 2017, 2:28 PM yperess notifications@github.com wrote:

Do you mean that R2 should contain something like switch_camera = com.example.R.id.switch_camera?

The generated R2 contains:

@IdRes public static final int switch_camera = 0x7f0c00c3;

Library R contains:

public static int switch_camera=0x7f0c00c3;

App R contains:

public static final int switch_camera=0x7f100186;

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub <

https://github.com/JakeWharton/butterknife/issues/974#issuecomment-307582304

, or mute the thread <

https://github.com/notifications/unsubscribe-auth/AAEEEa2WqVlUQFJrkbf4eN51xe6qAunuks5sCuBYgaJpZM4N2Lt3

.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub <

https://github.com/JakeWharton/butterknife/issues/974#issuecomment-307582702

, or mute the thread <

https://github.com/notifications/unsubscribe-auth/AJF_-jyrG-n5fPbVEtieVC2dv8aEdlUhks5sCuI7gaJpZM4N2Lt3

.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub < https://github.com/JakeWharton/butterknife/issues/974#issuecomment-307584267 , or mute the thread < https://github.com/notifications/unsubscribe-auth/AAEEEau8TfCy_YaeDLxoYly5uJJRAsm1ks5sCujpgaJpZM4N2Lt3

.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/JakeWharton/butterknife/issues/974#issuecomment-307585969, or mute the thread https://github.com/notifications/unsubscribe-auth/AJF_-qbzXm0QaWNEh0Awz-SYqQjMiIRPks5sCvDygaJpZM4N2Lt3 .

yperess commented 7 years ago

The above project when compiled generates a ViewBinding class that also uses constants instead of references.

JakeWharton commented 7 years ago

And it probably fails at runtime because of this.

On Sat, Jun 10, 2017 at 9:53 PM yperess notifications@github.com wrote:

The above project when compiled generates a ViewBinding class that also uses constants instead of references.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/JakeWharton/butterknife/issues/974#issuecomment-307600895, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEZzN1QtHa2RPNQhlv04hV4ylhVyTks5sC0iygaJpZM4N2Lt3 .

yperess commented 7 years ago

Actually it runs, I imagine if we add more modules or names with conflicts it would fail and it just by luck managed to merge the resources without modifying the values.

vanniktech commented 7 years ago

I also just hit this. The problem is that the R.id.myId and R2.id.myId are different.

I've also tried out the example and it does work surprisingly. @yperess have you found a way to make it work for your application?

yperess commented 7 years ago

@vanniktech No I haven't, I've been busy dealing with other things about our project so I just put a hold on using butterknife on our library modules for now. In theory what you could do is create a second pass. Attach a gradle task to run after generateReleaseSources (when the R.java file is created) then go through the .java files in the butterknife output directory and find all the constants that are also in the R.java file and replace them with references. It's sloppy but in theory it should work.

RileyGB commented 7 years ago

I have run in to this issue as well and have found a workaround. If you add a Java class and bind any resource in the same package which you are binding, then the resources in your Kotlin classes will resolve correctly.

For example, I include a java class called BindingHelper.java in every package where I bind resources in Kotlin with the following code:

public class BindingHelper { @BindString(R2.string.app_name) String appName; }

JakeWharton commented 7 years ago

The values are meant to be different between R and R2, by the way.

josh-burton commented 6 years ago

We've been using butterknife in kotlin library modules and its been working great.

But after updating to 9.0.0-SNAPSHOT we've run into this issue.

Are there changes in 9.0.0 that mean this will never work?

yperess commented 6 years ago

The guys at JetBrains just closed the ticket causing this. It's scheduled to be resolved in kapt 1.2.20

josh-burton commented 6 years ago

Oh great! Do you have a link to that ticket?

yperess commented 6 years ago

https://youtrack.jetbrains.com/issue/KT-18791

JakeWharton commented 6 years ago

So... no action to take?

yperess commented 6 years ago

From what I understand we wait. As soon as 1.2.20 is out I'll confirm and close this issue or update it.

JakeWharton commented 6 years ago

Thanks!

On Wed, Nov 8, 2017, 3:56 AM yperess notifications@github.com wrote:

From what I understand we wait. As soon as 1.2.20 is out I'll confirm and close this issue or update it.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/JakeWharton/butterknife/issues/974#issuecomment-342796129, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEER1oIy9QMTK4iD7i3kI2SGq7WyPWks5s0ZbXgaJpZM4N2Lt3 .

RiteshChandnani commented 6 years ago

I just updated to early access preview of Kotlin (version 1.2.20-eap-11) on Android studio and that binding issue is gone :)

yperess commented 6 years ago

That's correct, it does appear to be working in eap-11 and eap-33. @JakeWharton my vote is to leave this open until 1.2.20 goes into the main stream so that people can easily find adding the eap as a workaround until then, but totally your call.

kylannjohnson commented 6 years ago

For more fodder, it seems like this issue causes a lint error in AGP 3.1-alpha8. If we remove the @BindView(R2.id.some_id) from Kotlin classes, then the lint error goes away. We are also on Kotlin 1.2.20.

The warning given is just: Expected resource of type id

We'll either have to remove Butterknife or ignore for now.

MyDogTom commented 6 years ago

OnClick annotation is not working for me in library module. Is that the same problem as described here or should I create a separate issue?

ButterKnife: 9.0.0-SNAPSHOT Kotlin: 1.2.40 AGP: 3.1.2

For the following class

class MyFragment : BaseFragment() {

    @BindView(R2.id.textview_upsell_confirmation_title) lateinit var headlineTextView: TextView
    @BindView(R2.id.textview_upsell_confirmation_text) lateinit var confirmationTextView: TextView

    @OnClick(R2.id.button_premium_upsell_confirmation)
    internal fun upsellConfirmationClicked() {
    }
}

ButterKnife generates

  @UiThread
  public MyFragment_ViewBinding(
      final MyFragment target, View source) {
    this.target = target;

    View view;
    target.headlineTextView = Utils.findRequiredViewAsType(source, R.id.textview_upsell_confirmation_title, "field 'headlineTextView'", TextView.class);
    target.confirmationTextView = Utils.findRequiredViewAsType(source, R.id.textview_upsell_confirmation_text, "field 'confirmationTextView'", TextView.class);
    view = Utils.findRequiredView(source, 2131493117, "method 'upsellConfirmationClicked$core_app_debug'");
    view7f0c00fd = view;
    view.setOnClickListener(new DebouncingOnClickListener() {
      @Override
      public void doClick(View p0) {
      }
    });
  }

At runtime I'm receiving Caused by: android.content.res.Resources$NotFoundException: Unable to find resource ID

I noticed, that for @BindView generated code contains reference to R.id. But for @OnClick generated code contains hardcoded constant.

UPDATE: I also noticed that sometimes it happens like that, but sometimes binding for OnCLick is generated with reference to R.id.

idanatz commented 6 years ago

Having the same issue as @MyDogTom OnClick annotation generated code contains a reference to R.id. But for @OnClick generated code contains hardcoded constant and sometimes even a wrong R.id.

ButterKnife: 8.8.1 Kotlin: 1.2.50

flasher297 commented 5 years ago

Facing the same issue. Mixed Java/Kotlin project. For @OnClick annotation Butterknife picks up wrong view id. It could be id of other view on the screen or, sibling screen, or even some id that i don't use in the app.

butterKnifeVersion = '8.8.1' kotlin_version = '1.2.71'

Don't have such issue with pure Kotlin projects.

yperess commented 5 years ago

Have you tried butterknife 9.0.0-rc1?

On Tue, Oct 23, 2018, 06:25 Alex notifications@github.com wrote:

Facing the same issue. Mixed Java/Kotlin project. For @OnClick https://github.com/OnClick annotation Butterknife picks up wrong view id. It could be id of other view on the screen or, sibling screen, or even some id that i don't use in the app.

butterKnifeVersion = '8.8.1' kotlin_version = '1.2.71'

Don't have such issue with pure Kotlin projects.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JakeWharton/butterknife/issues/974#issuecomment-432190092, or mute the thread https://github.com/notifications/unsubscribe-auth/AJF_-lR9KcH98VGUAcbgKLaZepSlp0zlks5unu6ogaJpZM4N2Lt3 .

frett commented 5 years ago

It appears this issue was re-introduced with Kotlin 1.3.10.

R2 usage in a Kotlin class works correct with the following dependency versions: ButterKnife: 9.0.0-rc1 Kotlin: 1.2.71

Upgrading Kotlin to 1.3.10 causes the R2 resource to be replaced with a raw int and not the correct R id in the generated ViewBinding class

JakeWharton commented 5 years ago

It's fixed in 1.3.20

On Fri, Nov 16, 2018, 10:30 AM Daniel Frett <notifications@github.com wrote:

It appears this issue was re-introduced with Kotlin 1.3.10.

R2 usage in a Kotlin class works correct with the following dependency versions: ButterKnife: 9.0.0-rc1 Kotlin: 1.2.71

Upgrading Kotlin to 1.3.10 causes the R2 resource to be replaced with a raw int and not the correct R id in the generated ViewBinding class

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/JakeWharton/butterknife/issues/974#issuecomment-439429498, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEWSydeSaMxnIzqhgsTJhZELw8OOwks5uvtoagaJpZM4N2Lt3 .

oliverspryn commented 5 years ago

Good to know, waiting for 1.3.20 to hit stable before retrying butterknife. Using Kotlin extensions for the time being.

oliverspryn commented 5 years ago

1.3.20 is out 🎉 Didn't get a chance to check out Butterknife again, though

marcosalis commented 5 years ago

I have just tested Kotlin 1.3.20 (stable) with Butterknife 9.0.0 on library modules, and everything seems to be working fine! 👍

JakeWharton commented 5 years ago

Glad to hear it!

ysyyork commented 4 years ago

I have just tested Kotlin 1.3.20 (stable) with Butterknife 9.0.0 on library modules, and everything seems to be working fine! 👍

I just test the same kotlin 1.3.20 and butterknife 9.0.0 but the issue is still there? Are you sure about this? Also tested varies combination of kotlin and butterknife but nothing works. 1.3.50, 9.0.0 1.3.50, 10.0.0 1.3.30, 9.0.0

kkmike999 commented 4 years ago

the problem still here.

FragmentA

@BindView(R2.id.itemView)
lateinit var itemView: ViewGroup

@OnClick(R2.id.itemView)
fun onItemClick(view: View) {}

FragmentA_ViewBinding

View view;
view = Utils.findRequiredView(source, R.id.itemView, "field 'itemView' and method 'onItemClick'");

if i kon't write @BindView(R2.id.itemView),then FragmentA_ViewBinding will be:

View view;
view = Utils.findRequiredView(source, 2131427425, "method 'onItemClick'");

where is the R.id.itemView??

throw exception:

java.lang.IllegalStateException: Required view 'md_dialog_progress' with ID 2131427425 for method 'onItemClick' was not found. If this view is optional add '@Nullable' (fields) or '@Optional' (methods) annotation.
        at butterknife.internal.Utils.findRequiredView(Utils.java:88)
        at com.badambiz.live.fragment.FragmentA_ViewBinding.<init>(FragmentA_ViewBinding.java:24)

2131427425 is not equals R.id.itemView


classpath 'com.android.tools.build:gradle:3.4.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50"
classpath "com.jakewharton:butterknife-gradle-plugin:9.0.0"
apply plugin: 'com.jakewharton.butterknife'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

dependencies{
    api 'com.jakewharton:butterknife:9.0.0'
    kapt 'com.jakewharton:butterknife-compiler:9.0.0'
}
EchoAGI commented 4 years ago

the problem is still here, not fixed, fuck

ysyyork commented 4 years ago

@newtalentxp wowow easy man

vy12021 commented 4 years ago

Hi, guys above.

Stubs in kapt

After my analysis, I found that some annotation meta information was erased during the generation of the java stub file. In our question, the annotations on the member variables retained the reference information, but the annotation information on the member methods was replaced with constant. This will cause the generated ButterKnife file to find the symbol index of the id if no member variable with the same id is defined. I guess this may be a bug in kapt that generates stub files. What is doubtful is that there is a difference in the processing of the two member elements.

The default path of kapt stub : build/tmp/kapt3/stubs/debug/com.xxx.package/xxx.Java

20200221161442

@JakeWharton

vy12021 commented 4 years ago

the problem is still here, not fixed, fuck

@newtalentxp 大哥!你是键盘侠吗?不要公开丢中国人脸。