Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Gradle Plugin 3.5.1 databinding error with Kotiln Generic type

I am in the middle of trying to modularize a library so tbh anything could be going on here. After updating from the Android Gradle Plugin 3.5.0 to 3.5.1, I now get a databinding error on a layout which uses my Resource.kt class. The class I believe was lifted straight out of the Google Github Browser sample (I can't get the latest commit of that to build at all for some reason). The error seems to be specifically with the generic data field T.

Resource.kt

data class Resource<out T>(val status: Status, val data: T?, val message: String?, val throwable: Throwable? = null) {
    companion object {
        fun <T> success(data: T?): Resource<T> {
            return Resource(SUCCESS, data, null)
        }

        fun <T> error(data: T?, msg: String, throwable: Throwable?): Resource<T> {
            return Resource(ERROR, data, msg, throwable)
        }

        fun <T> loading(data: T?): Resource<T> {
            return Resource(LOADING, data, null)
        }
    }
}

Layout xml:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <import type="android.view.View" />

        <import type="core.sdk.data.remote.response.Resource" />

        <import type="core.sdk.data.remote.response.Status" />

        <variable
            name="resource"
            type="Resource" />

        <variable
            name="progressText"
            type="String" />
    </data>

    <LinearLayout
        android:id="@+id/circular_progress"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="vertical"
        app:visibleGone="@{resource.data == null}">

        <androidx.core.widget.ContentLoadingProgressBar
            android:id="@+id/progress_bar"
            style="@style/Widget.AppCompat.ProgressBar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:indeterminateTint="@color/ll_secondary"
            android:indeterminateTintMode="src_in"
            app:visibleGone="@{resource.status == Status.LOADING}"
            tools:ignore="UnusedAttribute" />

        <TextView
            android:id="@+id/progress_text_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:text="@{progressText}"
            android:textAppearance="?attr/textAppearanceHeadline5"
            android:textColor="@color/ll_secondary"
            android:textStyle="italic"
            app:visibleGone="@{resource.status == Status.LOADING}"
            tools:text="loading..." />
    </LinearLayout>

</layout>

Error:

LoadingStateBindingImpl.java:106: error: ';' expected ? resourceData = null; enter image description here

I have incremental databinding and kapt on:

android.databinding.incremental=true
kapt.incremental.apt=true

Project is a fully Kotlin using Kotlin 1.3.50 with a jvm target of 1.8:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

kotlinOptions {
    jvmTarget = "1.8"
}

This error does not appear with AGP 3.5.0. Here is the same file with 3.5.0 and no error:

enter image description here

like image 909
Daniel Wilson Avatar asked Nov 07 '22 13:11

Daniel Wilson


1 Answers

This is unfortunately a change to how databinding works, and judging from the issue tracker discussion this is a permanent change.

Databinding references are now a bit stricter, so using a generic class - in this case Resource - will fail. Similarly using something like List:

<variable name="list" type="java.util.List"/>

will also fail. Because databinding doesn't have enough information to work out what the generic type is - someone with more knowledge of generics may be able to explain why this is the case!

In order to handle the generics, Databinding needs more information. There's two ways to update databinding to work with the new gradle plugin:

  1. Directly define your generic. "&lt" is the xml equivalent to "<".
<variable name="list" type="java.util.List&lt;MyClass>"/>
  1. Wrap your generic in a containing class.
class MyGenericWrapper : List<Object>  

<variable name="myVariable" type="MyGenericWrapper"/>
like image 113
enyciaa Avatar answered Nov 14 '22 21:11

enyciaa