Status Update
Comments
[Deleted User] <[Deleted User]> #2
Android sdk build tools: 29.0.2
Android gradle plugin: 3.6.0-beta02
da...@google.com <da...@google.com> #3
[Deleted User] <[Deleted User]> #4
yb...@google.com <yb...@google.com> #5
[Deleted User] <[Deleted User]> #6
update. By standard I mean clicking on dialogs. But I'll try to install
beta-01, update again and list the steps.
I'll also try with 4.0 as soon as I hit the office !
Le lun. 4 nov. 2019 à 00:09, <buganizer-system@google.com> a écrit :
[Deleted User] <[Deleted User]> #7
Update from beta 1 to beta 2:
- Studio dialog plugin update: click Update and Restart (elevator start the update)
Studio restart
- Ask for android gradle plugin update to 3.6.0-beta02
- Gradle build failed for same reason
sc...@gmail.com <sc...@gmail.com> #8
sc...@gmail.com <sc...@gmail.com> #9
I had a few cases where I was using a binding expression like @{safeUnbox(viewModel.booleanObservable.get())}
removing the .get() caused the StackOverflowException to go away and my build succeeds now.
@{safeUnbox(viewModel.booleanObservable)}
[Deleted User] <[Deleted User]> #10
da...@google.com <da...@google.com> #11
[Deleted User] <[Deleted User]> #12
"error: cannot generate view binders java.lang.StackOverflowError
at android.databinding.tool.expr.Expr.resolveListeners(Expr.java:209)"
Attached is our sample project and the "get()" is underlined in red.
[Deleted User] <[Deleted User]> #13
Data.java
public class Data {
@NonNull public MutableLiveData<Boolean> isSendEnabled = new MutableLiveData<>();
}
mylibrary.xml
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:width="@{data.isSendEnabled.getValue()}" />
da...@google.com <da...@google.com> #14
I don't think this means the compile error shouldn't be fixed, but at least for new users, the red underline may help prevent the problem from happening in the first place.
[Deleted User] <[Deleted User]> #15
I had two liveData .getValue() on old layouts ! Both were underlined, but I had too much databinding views to go through all of them.
al...@gmail.com <al...@gmail.com> #16
I'm experiencing "error: cannot generate view binders java.lang.StackOverflowError" after upgrading to Android Gradle Plugin v3.5.2.
This is my code (as you can see it worked for a lot of time):
package com.example.fisher_lib;
import android.view.View;
import androidx.databinding.BindingAdapter;
import androidx.databinding.DataBindingComponent;
import androidx.recyclerview.widget.RecyclerView;
import com.example.fisher_lib.enums.statistic.RepresentationType;
import com.example.fisher_lib.enums.statistic.StatisticType;
/**
* Created by Alessandro Frigerio on 11/04/2018.
*/
public class FisherBindingAdapter {
@BindingAdapter(value = {"provider", "representationType", "statisticType"})
public static <T extends View & FisherDataView> void loadData(DataBindingComponent component, T view, FisherDataDescriptor dataProvider, RepresentationType representationType, StatisticType statisticType) {
dataProvider.loadData(view, representationType, statisticType);
}
@BindingAdapter("provider")
public static void loadData(RecyclerView view, FisherDataDescriptor dataProvider) {
dataProvider.loadData(view);
}
}
yb...@google.com <yb...@google.com> #17
data binding used to ignore some type parameters which would cause problems so maybe just some description is missing in the layout.
al...@gmail.com <al...@gmail.com> #18
RepresentationType and StatisticType are just enum
////////////////////////////////////////////////////////////
//////////////// Layout ////////////////
////////////////////////////////////////////////////////////
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="
<data>
<variable
name="vm"
type="com.example.fisher_lib.FisherDataDescriptor" />
<import type="com.example.enums.statistic.StatisticType" />
<import type="com.example.enums.statistic.RepresentationType" />
</data>
<LinearLayout xmlns:android="
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.example.libs.fisher_lib.FisherPercentageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:provider="@{vm}"
app:representationType="@{RepresentationType.PERCENTAGE}"
app:statisticType="@{StatisticType.MISSION_AVERAGE_EXECUTION_TIME}" />
</LinearLayout>
</layout>
//////////////////////////////////////////////////////////////
//////////////// Variable ////////////////
//////////////////////////////////////////////////////////////
package com.example.fisher_lib;
import androidx.databinding.BaseObservable;
import androidx.databinding.ObservableArrayMap;
import androidx.databinding.ObservableBoolean;
import androidx.databinding.ObservableField;
import androidx.recyclerview.widget.RecyclerView;
import java.util.Collections;
import java.util.List;
import io.reactivex.Maybe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import com.example.enums.statistic.RepresentationType;
import com.example.enums.statistic.StatisticType;
import com.example.models.singleton.DaemonData;
/**
* Created by Alessandro Frigerio on 11/04/2018.
*/
public class FisherDataDescriptor extends BaseObservable {
public ObservableBoolean hasDynamicData = new ObservableBoolean();
public ObservableArrayMap<String, FisherHead> staticFisherHeads = new ObservableArrayMap<>();
public ObservableField<FisherAdapter> fisherAdapter = new ObservableField<>(new FisherAdapter(Collections.emptyList()));
public static String getStatisticKey(RepresentationType representationType, StatisticType statisticType) {
return representationType.getValue() + "_" + statisticType.getValue();
}
public void loadData(FisherDataView view, RepresentationType representationType, StatisticType statisticType) {
getSpecificFisherHead(representationType, statisticType)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(result -> view.setFisherHead(result));
}
public void loadData(final RecyclerView view) {
DaemonData.data.statisticModel.rxGetDynamics()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(result -> {
FisherAdapter adapter = new FisherAdapter(result);
view.setAdapter(adapter);
hasDynamicData.set(result.size() > 0);
});
}
public void putStaticFisherHead(RepresentationType representationType, StatisticType statisticType, FisherHead head) {
String key = getStatisticKey(representationType, statisticType);
staticFisherHeads.put(key, head);
}
public void setDynamicData(List<FisherHead> fisherHeads) {
fisherAdapter.set(new FisherAdapter(fisherHeads));
hasDynamicData.set(fisherHeads.size() > 0);
}
private Maybe<FisherHead> getSpecificFisherHead(RepresentationType representationType, StatisticType statisticType) {
return DaemonData.data.statisticModel.rxGetSpecific(representationType, statisticType);
}
}
//////////////////////////////////////////////////////////////
//////////////// Generated Binding ///////////////
//////////////////////////////////////////////////////////////
package com.example.databinding;
import com.example.R;
import
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.view.View;
@SuppressWarnings("unchecked")
public class FragmentHalfpieBindingImpl extends FragmentHalfpieBinding {
@Nullable
private static final androidx.databinding.ViewDataBinding.IncludedLayouts sIncludes;
@Nullable
private static final android.util.SparseIntArray sViewsWithIds;
static {
sIncludes = null;
sViewsWithIds = null;
}
// views
@NonNull
private final android.widget.LinearLayout mboundView0;
@NonNull
private final com.example.libs.fisher_lib.FisherPercentageView mboundView1;
// variables
// values
// listeners
// Inverse Binding Event Handlers
public FragmentHalfpieBindingImpl(@Nullable androidx.databinding.DataBindingComponent bindingComponent, @NonNull View root) {
this(bindingComponent, root, mapBindings(bindingComponent, root, 2, sIncludes, sViewsWithIds));
}
private FragmentHalfpieBindingImpl(androidx.databinding.DataBindingComponent bindingComponent, View root, Object[] bindings) {
super(bindingComponent, root, 1
);
this.mboundView0 = (android.widget.LinearLayout) bindings[0];
this.mboundView0.setTag(null);
this.mboundView1 = (com.example.libs.fisher_lib.FisherPercentageView) 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) {
boolean variableSet = true;
if (BR.vm == variableId) {
setVm((com.example.libs.fisher_lib.FisherDataDescriptor) variable);
}
else {
variableSet = false;
}
return variableSet;
}
public void setVm(@Nullable com.example.libs.fisher_lib.FisherDataDescriptor Vm) {
updateRegistration(0, Vm);
this.mVm = Vm;
synchronized(this) {
mDirtyFlags |= 0x1L;
}
notifyPropertyChanged(BR.vm);
super.requestRebind();
}
@Override
protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {
switch (localFieldId) {
case 0 :
return onChangeVm((com.example.libs.fisher_lib.FisherDataDescriptor) object, fieldId);
}
return false;
}
private boolean onChangeVm(com.example.libs.fisher_lib.FisherDataDescriptor Vm, int fieldId) {
if (fieldId == BR._all) {
synchronized(this) {
mDirtyFlags |= 0x1L;
}
return true;
}
return false;
}
@Override
protected void executeBindings() {
long dirtyFlags = 0;
synchronized(this) {
dirtyFlags = mDirtyFlags;
mDirtyFlags = 0;
}
com.example.libs.fisher_lib.FisherDataDescriptor vm = mVm;
if ((dirtyFlags & 0x3L) != 0) {
}
// batch finished
if ((dirtyFlags & 0x3L) != 0) {
// api target 1
com.example.libs.fisher_lib.FisherBindingAdapter.loadData(this.mBindingComponent, this.mboundView1, vm, com.example.enums.statistic.RepresentationType.PERCENTAGE, com.example.enums.statistic.StatisticType.MISSION_AVERAGE_EXECUTION_TIME);
}
}
// Listener Stub Implementations
// callback impls
// dirty flag
private long mDirtyFlags = 0xffffffffffffffffL;
/* flag mapping
flag 0 (0x1L): vm
flag 1 (0x2L): null
flag mapping end*/
//end
}
al...@gmail.com <al...@gmail.com> #19
public class FisherPercentageView extends LinearLayout implements FisherDataView {
...
}
public interface FisherDataView {
void setFisherHead(FisherHead fisherHead);
}
ku...@digitaldolphins.jp <ku...@digitaldolphins.jp> #20
To locate problem part of `cannot generate view binders java.lang.StackOverflowError`,
Run `gradlew testDebugUnitTest -d`
And search message like: `e: error: found recursive type, canceling resolution: viewModel.variableName.get()`
yb...@google.com <yb...@google.com> #21
Do you mind trying to create a sample project that would recreate the issue?
Enclosed is the sample i created. (please ignore extra files, it is my goto sample creator :) )
yb...@google.com <yb...@google.com> #22
./gradlew clean asDebug --debug > log.txt
then
grep 'writing\ data\ binder\|writing\ file' log.txt
each file will get first "writing data binder" then "writing file". The problematic file won't have "writing file" (it would be nice if we didn't fail compilation that fast though :), something to improve on the data binding side)
yb...@google.com <yb...@google.com> #23
closing since we cannot reproduce. feel free to re-submit if you can create a repro, thanks!
ku...@gmail.com <ku...@gmail.com> #24
The offending line was:
```
android:visibility="@{data.myObservableString.get() != null ? View.VISIBLE : View.INVISIBLE}"
```
da...@google.com <da...@google.com> #25
Thanks for the report and sorry for the trouble. Yes - it's a known issue. The solution is to remove get()
from your code. Studio should show you an IDE warning for that I believe?
ku...@gmail.com <ku...@gmail.com> #26
I understand it is a known issue, but it was pretty hard to track down the issue, since the stacktrace is just a StackOverflowError. There is no telling what layout it failed on, so the fact that this is closed as 'Won't Fix' is concerning. The linked issue has a "fix" which is adding static analysis around this, but perhaps the exception thrown could have some more information like the layout name, rather than just "cannot generate view binders".
yb...@google.com <yb...@google.com> #27
yea the exception can definitely be improved. i think the problem is that when the error happens, it bubbles to a step where we don't know which layout caused the issue, we should probably catch it earlier and report w/ better diagnostics. re-opening for that.
yb...@google.com <yb...@google.com> #28
We've made a change to re-allow these as data binding itself generates similar expressions for two way binding and it that case, unfortunately, it is legit. So it just makes sense to allow this but keep it as an error in the ide since it is never desired by the developer.
As part of
yb...@google.com <yb...@google.com> #29
fixing this since now we'll provide better information when it fails and also re-allowed the unnecessary observable calls.
Description
I've just updated my Studio to the latest beta version, and I'm not able to compile my project anymore.
e: error: cannot generate view binders java.lang.StackOverflowError
at android.databinding.tool.expr.Expr.resolveListeners(Expr.java:209)
at android.databinding.tool.expr.Expr.resolveListeners(Expr.java:211)
Can't explain this issue more, the last line repeat for like a thousand times before the error log stops.