构建Android FTC机器人自定义库时java.lang.NullPointerException问题求助
自定义FTC机器人库Gradle构建NPE错误排查与解决
开发自定义FTC机器人库以简化开发流程时,尝试发布至MavenCentral、MavenLocal及GitHub Pages均出现相同错误;将库作为模块加入RobotController Android Studio项目后,问题仍存在。错误关联Gradle任务ExtDexDebugAndroidTest及publish.gradle生成的jar,核心报错为java.lang.NullPointerException。
项目配置文件
build.gradle
plugins { id 'com.android.library' } android { namespace 'org.overture.ftc.overftclib' compileSdk 34 defaultConfig { minSdkVersion 16 aarMetadata{ minCompileSdk = 29 } testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" consumerProguardFiles "consumer-rules.pro" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { implementation 'androidx.appcompat:appcompat:1.7.0' implementation 'com.google.android.material:material:1.10.0' implementation project(':FtcRobotController') testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' }
publish.gradle
apply plugin: 'maven-publish' ext.licenseFile = files("$rootDir/LICENSE.txt") def pubVersion = '0.0.1' def outputsFolder = file("$buildDir/outputs") def versionFile = file("$outputsFolder/version.txt") task outputVersions() { description = 'Prints the version of the library to a file' group = 'Build' outputs.files(versionFile) doFirst { buildDir.mkdir() outputsFolder.mkdir() } doLast { versionFile.write pubVersion } } task libraryBuild() {} build.dependsOn outputVersions task copyAllOutputs(type: Copy) { destinationDir file("$buildDir/allOutputs") from versionFile dependsOn outputVersions } build.dependsOn copyAllOutputs copyAllOutputs.dependsOn outputVersions ext.addTaskToCopyAllOutputs = { task -> copyAllOutputs.dependsOn task copyAllOutputs.inputs.file task.archiveFile copyAllOutputs.from task.archiveFile } def artifactGroupId = 'com.overture.ftc.lib' def baseArtifactId = 'OvertureFTCLib' // Tasks for creating additional artifacts, like sources and Javadoc task androidSourcesJar(type: Jar) { classifier = 'sources' from android.sourceSets.main.java.srcDirs } task androidJavadocs(type: Javadoc) { source = android.sourceSets.main.java.srcDirs classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) } task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) { classifier = 'javadoc' from androidJavadocs.destinationDir } build.dependsOn androidSourcesJar build.dependsOn androidJavadocsJar addTaskToCopyAllOutputs(androidSourcesJar) addTaskToCopyAllOutputs(androidJavadocsJar) libraryBuild.dependsOn build def releasesRepoUrl = "$buildDir/repos/releases" publishing { publications { androidLibrary(MavenPublication) { groupId = artifactGroupId artifactId = baseArtifactId version = pubVersion afterEvaluate { from components.release } artifact androidSourcesJar artifact androidJavadocsJar } } repositories { maven { url = releasesRepoUrl } } } task cleanReleaseRepo(type: Delete) { delete releasesRepoUrl } tasks.matching { it != cleanReleaseRepo }.all { it.dependsOn cleanReleaseRepo }
错误详情
> Task :overftclib:mergeExtDexDebugAndroidTest AGPBI: {"kind":"error","text":"java.lang.NullPointerException: Cannot invoke \"String.length()\" because \"<parameter1>\" is null","sources":[{"file":"C:\\Users\\santy\\.gradle\\caches\\transforms-3\\9d823f17cc7bfaba9537b6c404b8a19f\\transformed\\appcompat-resources-1.7.0-runtime.jar"}],"tool":"D8"} AGPBI: {"kind":"error","text":"java.lang.NullPointerException: Cannot invoke \"String.length()\" because \"<parameter1>\" is null","sources":[{"file":"C:\\Users\\santy\\.gradle\\caches\\transforms-3\\6303bfbaba1977f71e281e2c3baabe3f\\transformed\\appcompat-1.7.0-runtime.jar"}],"tool":"D8"} AGPBI: {"kind":"error","text":"java.lang.NullPointerException","sources":[{"file":"C:\\Users\\santy\\.gradle\\caches\\transforms-3\\6303bfbaba1977f71e281e2c3baabe3f\\transformed\\appcompat-1.7.0-runtime.jar"}],"tool":"D8"} > Task :overftclib:mergeExtDexDebugAndroidTest FAILED
核心错误栈:
java.lang.NullPointerException: Cannot invoke "String.length()" because "<parameter1>" is null
问题分析与解决方案
问题本质
该NPE是D8编译器处理appcompat依赖包时,遇到空字符串参数触发的异常,常见诱因包括:Gradle/AGP版本与依赖版本不兼容、本地构建缓存损坏、任务依赖逻辑冲突。
分步解决方案
清理构建缓存
执行Gradle清理命令并删除本地缓存目录:./gradlew clean build --no-build-cache手动删除Windows本地缓存路径:
C:\Users\santy\.gradle\caches,避免损坏缓存文件干扰构建。调整依赖与AGP版本
- 升级项目根目录
build.gradle中的AGP版本至与compileSdk 34兼容的版本(如7.4.2):dependencies { classpath 'com.android.tools.build:gradle:7.4.2' } - 降低appcompat依赖版本至更稳定的1.6.1,规避高版本与FTC SDK的兼容性冲突:
implementation 'androidx.appcompat:appcompat:1.6.1'
- 升级项目根目录
禁用AndroidTest相关任务
FTC库核心用于机器人运行,可暂时禁用测试任务避免Dex合并冲突,在库模块build.gradle中添加:android { // 其他配置保持不变 tasks.whenTaskAdded { task -> if (task.name.contains('AndroidTest')) { task.enabled = false } } }修复publish.gradle任务依赖
当前配置中cleanReleaseRepo被设为所有任务的依赖,会反复清理仓库干扰jar生成,注释或移除以下代码:// tasks.matching { it != cleanReleaseRepo }.all { it.dependsOn cleanReleaseRepo }
内容的提问来源于stack exchange,提问作者Santiago Quintana
相关产品推荐
相关产品推荐

