AndroidX与DataBinding不兼容

8
好的,我被委托将一个项目迁移到AndroidX,以减少在我们的项目中使用的支持库的混乱。我已经按照官方文档启用了AndroidX,但现在当我尝试通过对应的自动生成的绑定类来填充视图时,我会遇到运行时错误,这些绑定类是从模块gradle中启用数据绑定时创建的。
挖掘自动生成的源代码,我发现了这个方法,这是导致代码抛出异常的方法:
   public List<DataBinderMapper> collectDependencies() {
        ArrayList<DataBinderMapper> result = new ArrayList(1);
        result.add(new com.android.databinding.library.baseAdapters.DataBinderMapperImpl());
        return result;
    }

如您所见,自动生成的代码试图从com.android.databinding包中实例化一个类,但是由于我从gradle中删除了支持依赖项(因为AndroidX应该替换它们),该包在输出APK中不存在。我可以看到Androidx有一个databinding包,因此我假设上面的自动生成代码应该引用androidx.databinding包,但事实并非如此。
这是工具问题还是我的配置有误?
下面是我的gradle文件(由于安全原因,某些部分被省略):
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'

//These variable refer to release builds so make sure they are correct. If you need to override them
//for some specific development needs then use variables that can be passed to gradle on command line.
String releaseVersionName = '1.0.0'
int releaseVersionCode = 1
int releaseMinSdk = 18
int releaseCompileSdkVersion = 28

android {
    //Added as separate variable so it can be overridden from IDE to speed up compilation time
    //Set minimum compilation sdk.
    int developMinSdk = rootProject.hasProperty('productMinSdk') ?
            rootProject.productMinSdk.toInteger() : releaseMinSdk
    String developProductVersionName = rootProject.hasProperty('productVersionName') ?
            rootProject.productVersionName : releaseVersionName
    int developProductVersionCode = System.getenv("BUILD_ID") as Integer ?: releaseVersionCode
    int developCompileSdk = rootProject.hasProperty('productCompileSdk') ?
            rootProject.productCompileSdk.toInteger() : releaseCompileSdkVersion

    defaultConfig {
        applicationId "..."
        compileSdkVersion developCompileSdk
        minSdkVersion developMinSdk
        targetSdkVersion developCompileSdk
        versionCode developProductVersionCode
        versionName developProductVersionName

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    signingConfigs {
       ...
    }

    sourceSets {
        ...
    }

    buildTypes {
        debug {
            signingConfig signingConfigs.release
            dexOptions {
                jumboMode = true
                javaMaxHeapSize "1g"
            }
            multiDexEnabled true
            matchingFallbacks = ['debug', 'release']
        }
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
            dexOptions {
                jumboMode = true
                javaMaxHeapSize "1g"
            }
        }
    }

    flavorDimensions "default"

    productFlavors {
        //noinspection GroovyMissingReturnStatement
        develop {
            applicationIdSuffix ".develop"
            dimension "default"
            sourceSets {
                develop.java.srcDirs += 'src/develop/kotlin'
            }
        }

        //Normal build for release
        //noinspection GroovyMissingReturnStatement
        playstore {
            //In this flavour we use release* variable explicitly so they cannot be
            //overridden by mistake
            //Force min sdk version from the global variable
            minSdkVersion releaseMinSdk
            //Force version name from the global variables
            versionName releaseVersionName
            //Force version code from the global variable
            versionCode releaseVersionCode
            //Force compile and target sdk versions from the global variable
            compileSdkVersion releaseCompileSdkVersion
            targetSdkVersion releaseCompileSdkVersion
            dimension "default"
            sourceSets {
                playstore.java.srcDirs += 'src/playstore/kotlin'
            }
        }
    }

    dataBinding {
        enabled = true
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    // Runtime dep versions
    def condecoCoreVersion = "0.1.3"
    def appCenterVersion = "1.9.0"
    def thirtyinchVersion = '0.9.0'
    def stethoVersion = "1.5.0"
    def leakCanaryVersion = '1.5.4'
    def hahaVersion = "1.3"
    def multiDexVersion = "2.0.0"
    def constraintLayoutVersion = "1.1.3"

    // Test dep versions
    def jUnitVersion = "4.12"

    // Std lib dependency
    implementation group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jdk8', version: "$kotlin_version"
    implementation group: 'org.jetbrains.kotlin', name: 'kotlin-reflect', version: "$kotlin_version"

    // Multidex dependency
    implementation "androidx.multidex:multidex:$multiDexVersion"

    // Junit dependency for testing
    testImplementation "junit:junit:$jUnitVersion"
}

这是我的 gradle.properties 文件:

# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official

# Use androidX to replace requirement for
# Support libraries to be imported via gradle
android.useAndroidX=true

# Jetifier automatically updates dependancy binaries
# To swap out support lib for androix
android.enableJetifier=true

编辑:这是我的项目级别gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext {
        kotlin_version = '1.2.71'
        gradle_plugin_version = '3.2.1'
    }

    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath "com.android.tools.build:gradle:$gradle_plugin_version"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        mavenCentral()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

在依赖项中添加 kapt "com.android.databinding:compiler:$android_plugin_version",并让我知道它是否有帮助。android_plugin_version 是项目级别 Gradle 中 com.android.tools.build:gradle 的版本。 - Khemraj Sharma
很遗憾,结果完全相同。 - Thomas Cook
1
我有3.3.0-beta01版本,代码如下:result.add(new androidx.databinding.library.baseAdapters.DataBinderMapperImpl()); - pskink
1
result.add(new androidx.databinding.library.baseAdapters.DataBinderMapperImpl()); - Khemraj Sharma
1
只需要运行 rm -rf build 命令即可彻底删除 build 文件夹。 - pskink
显示剩余18条评论
1个回答

11

好的,最终解决了这个问题。

问题是我使用的库依赖于Android数据绑定(而不是AndroidX数据绑定)。

尽管我在 gradle.properties 文件中启用了Jetifier,但由于某种原因,库二进制文件没有将Android数据绑定替换为相应的AndroidX版本。幸运的是,这个库是我们内部的,所以我已经更新了库以迁移到AndroidX,这个噩梦就解决了。

感谢所有的建议,希望这个答案能帮助任何遇到类似问题的人,因为这花费了我两个工作日来解决!


我遇到了和你一样的问题,但不幸的是,这个库不是我的。生成的绑定类中,android.support.v7.widget.Toolbar 类没有更新为 androidx.appcompat.widget.Toolbar - NamNH
你尝试过清理项目并重新构建吗?生成的绑定类可能已被缓存,因此简单的构建可能不会导致这些缓存的生成类被重新构建。 - Thomas Cook
1
你的评论让我省去了一周的头疼,我没有意识到有两种数据绑定(即androidx.databinding和databinding)。我创建了自己的gradle.properties文件并启用了androidx和jetifier,它起了魔法般的作用。感谢您的洞察力。 - Tonnie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接