Fixed
Status Update
Comments
ar...@google.com <ar...@google.com> #2
We use build flavours heavily with a lot of common code. The refactoring support in AS is really good but it continually catches us out when it doesn't work across all flavours in a project. It's a big gap for serious product development.
ar...@google.com <ar...@google.com> #3
We at my company need this same feature. We have a lot of white labels and need refactor the same class across flavours. :(
Description
com.android.databinding:library:1.3.1
com.android.databinding:baseLibrary:3.0.0-alpha6
com.android.databinding:adapters:1.3.1
Steps
1. I created a layout for data binding and use 2-way binding.
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="
xmlns:app="
xmlns:tools="
<data>
<variable name="accepted" type="boolean"/>
</data>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.mokelab.demo.databinding.MainActivity">
<TextView
android:id="@android:id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@android:id/text1"
android:checked="@={accepted}"/>
</android.support.constraint.ConstraintLayout>
</layout>
2. put the same layout on layout-h480dp
3. Rebuild project on Android Studio or `sh gradlew assembleDebug`
What happened
Compile error happened. Data binding library generated broken code.
error message
/Users/fkm/dev/DataBindingErrorPattern/app/build/generated/source/apt/debug/com/mokelab/demo/databinding/databinding/ActivityMainBindingImpl.java:39: error: not an enclosing class: ActivityMainBinding
if ((com.mokelab.demo.databinding.databinding.ActivityMainBinding.this) != (null)) {
^
/Users/fkm/dev/DataBindingErrorPattern/app/build/generated/source/apt/debug/com/mokelab/demo/databinding/databinding/ActivityMainBindingImpl.java:39: error: illegal start of type
if ((com.mokelab.demo.databinding.databinding.ActivityMainBinding.this) != (null)) {
^
/Users/fkm/dev/DataBindingErrorPattern/app/build/generated/source/apt/debug/com/mokelab/demo/databinding/databinding/ActivityMainBindingImpl.java:43: error: not an enclosing class: ActivityMainBinding
com.mokelab.demo.databinding.databinding.ActivityMainBinding.this.setAccepted(callbackArg_0);
^
/Users/fkm/dev/DataBindingErrorPattern/app/build/generated/source/apt/debug/com/mokelab/demo/databinding/databinding/ActivityMainBindingH480dpImpl.java:39: error: not an enclosing class: ActivityMainBinding
if ((com.mokelab.demo.databinding.databinding.ActivityMainBinding.this) != (null)) {
^
/Users/fkm/dev/DataBindingErrorPattern/app/build/generated/source/apt/debug/com/mokelab/demo/databinding/databinding/ActivityMainBindingH480dpImpl.java:39: error: illegal start of type
if ((com.mokelab.demo.databinding.databinding.ActivityMainBinding.this) != (null)) {
^
/Users/fkm/dev/DataBindingErrorPattern/app/build/generated/source/apt/debug/com/mokelab/demo/databinding/databinding/ActivityMainBindingH480dpImpl.java:43: error: not an enclosing class: ActivityMainBinding
com.mokelab.demo.databinding.databinding.ActivityMainBinding.this.setAccepted(callbackArg_0);
^
6 errors
Generated code ( I added // !!! comment to explain)
package com.mokelab.demo.databinding.databinding;
import com.mokelab.demo.databinding.R;
import
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
@SuppressWarnings("unchecked")
public class ActivityMainBindingImpl extends ActivityMainBinding {
@Nullable
private static final android.databinding.ViewDataBinding.IncludedLayouts sIncludes;
@Nullable
private static final android.util.SparseIntArray sViewsWithIds;
static {
sIncludes = null;
sViewsWithIds = new android.util.SparseIntArray();
sViewsWithIds.put(android.R.id.text1, 2);
}
// views
@NonNull
private final android.support.constraint.ConstraintLayout mboundView0;
@NonNull
private final android.widget.CheckBox mboundView1;
// variables
// values
// listeners
// Inverse Binding Event Handlers
private android.databinding.InverseBindingListener mboundView1androidCheckedAttrChanged = new android.databinding.InverseBindingListener() {
@Override
public void onChange() {
// Inverse of accepted
// is com.mokelab.demo.databinding.databinding.ActivityMainBinding.this.setAccepted(callbackArg_0)
boolean callbackArg_0 = mboundView1.isChecked();
// localize variables for thread safety
// accepted
boolean accepted = mAccepted;
// !!! parent class is ActivityMainBindingImpl but library generates wrong class.... !!!
if ((com.mokelab.demo.databinding.databinding.ActivityMainBinding.this) != (null)) {
com.mokelab.demo.databinding.databinding.ActivityMainBinding.this.setAccepted(callbackArg_0);
}
}
};
public ActivityMainBindingImpl(@Nullable android.databinding.DataBindingComponent bindingComponent, @NonNull View root) {
this(bindingComponent, root, mapBindings(bindingComponent, root, 3, sIncludes, sViewsWithIds));
}
private ActivityMainBindingImpl(android.databinding.DataBindingComponent bindingComponent, View root, Object[] bindings) {
super(bindingComponent, root, 0
, (android.widget.TextView) bindings[2]
);
this.mboundView0 = (android.support.constraint.ConstraintLayout) bindings[0];
this.mboundView0.setTag(null);
this.mboundView1 = (android.widget.CheckBox) bindings[1];
this.mboundView1.setTag(null);
setRootTag(root);
// listeners
invalidateAll();
}
@Override
public void invalidateAll() {
synchronized(this) {
mDirtyFlags = 0x2L;
}
requestRebind();
}
@Override
public boolean hasPendingBindings() {
synchronized(this) {
if (mDirtyFlags != 0) {
return true;
}
}
return false;
}
@Override
public boolean setVariable(int variableId, @Nullable Object variable) {
switch(variableId) {
case BR.accepted :
setAccepted((boolean) variable);
return true;
}
return false;
}
public void setAccepted(boolean Accepted) {
this.mAccepted = Accepted;
synchronized(this) {
mDirtyFlags |= 0x1L;
}
notifyPropertyChanged(BR.accepted);
super.requestRebind();
}
@Override
protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {
switch (localFieldId) {
}
return false;
}
@Override
protected void executeBindings() {
long dirtyFlags = 0;
synchronized(this) {
dirtyFlags = mDirtyFlags;
mDirtyFlags = 0;
}
boolean accepted = mAccepted;
if ((dirtyFlags & 0x3L) != 0) {
}
// batch finished
if ((dirtyFlags & 0x3L) != 0) {
// api target 1
android.databinding.adapters.CompoundButtonBindingAdapter.setChecked(this.mboundView1, accepted);
}
if ((dirtyFlags & 0x2L) != 0) {
// api target 1
android.databinding.adapters.CompoundButtonBindingAdapter.setListeners(this.mboundView1, (android.widget.CompoundButton.OnCheckedChangeListener)null, mboundView1androidCheckedAttrChanged);
}
}
// Listener Stub Implementations
// callback impls
// dirty flag
private long mDirtyFlags = 0xffffffffffffffffL;
/* flag mapping
flag 0 (0x1L): accepted
flag 1 (0x2L): null
flag mapping end*/
//end
}
I pushed the minimum project to reproduce this.