AndroidX 与 DataBinding 不兼容 Android
AndroidX incompatible with DataBinding Android
好的,我的任务是将一个项目迁移到 AndroidX,以减少我们项目中支持库的混乱。我已经按照官方文档启用了 AndroidX,但现在我在尝试通过相应的自动生成的绑定 class 扩展视图时遇到 运行 时间错误,这些绑定是通过在模块中启用数据绑定创建的 class =32=].
深入研究自动生成的源代码,我发现了这个方法,它是导致代码抛出的方法:
public List<DataBinderMapper> collectDependencies() {
ArrayList<DataBinderMapper> result = new ArrayList(1);
result.add(new com.android.databinding.library.baseAdapters.DataBinderMapperImpl());
return result;
}
如您所见,自动生成的代码试图从 com.android.databinding
包中实例化一个 class,但是输出 APK 中不存在该包,因为我已经删除了支持来自我的 gradle 的依赖项(因为 AndroidX 应该替换它们)。我可以看到 androidx 有一个数据绑定包,所以我假设上面的自动生成的代码应该引用 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
}
好的,终于破解了。
问题是我使用的库依赖于 android 数据绑定(而不是 androidx 数据绑定)。
尽管我在我的 gradle.properties
文件中启用了 Jetifier,但出于某种原因,库二进制文件没有将 android 数据绑定换成相应的 androidx 版本。幸运的是,库在内部,所以我更新了库以迁移到 androidx,这整个噩梦自行解决了。
感谢所有建议,希望这个答案能帮助遇到类似问题的任何人,因为我花了 2 个工作日才弄明白!
好的,我的任务是将一个项目迁移到 AndroidX,以减少我们项目中支持库的混乱。我已经按照官方文档启用了 AndroidX,但现在我在尝试通过相应的自动生成的绑定 class 扩展视图时遇到 运行 时间错误,这些绑定是通过在模块中启用数据绑定创建的 class =32=].
深入研究自动生成的源代码,我发现了这个方法,它是导致代码抛出的方法:
public List<DataBinderMapper> collectDependencies() {
ArrayList<DataBinderMapper> result = new ArrayList(1);
result.add(new com.android.databinding.library.baseAdapters.DataBinderMapperImpl());
return result;
}
如您所见,自动生成的代码试图从 com.android.databinding
包中实例化一个 class,但是输出 APK 中不存在该包,因为我已经删除了支持来自我的 gradle 的依赖项(因为 AndroidX 应该替换它们)。我可以看到 androidx 有一个数据绑定包,所以我假设上面的自动生成的代码应该引用 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
}
好的,终于破解了。
问题是我使用的库依赖于 android 数据绑定(而不是 androidx 数据绑定)。
尽管我在我的 gradle.properties
文件中启用了 Jetifier,但出于某种原因,库二进制文件没有将 android 数据绑定换成相应的 androidx 版本。幸运的是,库在内部,所以我更新了库以迁移到 androidx,这整个噩梦自行解决了。
感谢所有建议,希望这个答案能帮助遇到类似问题的任何人,因为我花了 2 个工作日才弄明白!