我正在尝试将 RN 从 0.72 升级到 0.73.9
我在 Jenkins 中收到以下错误(我无法在本地计算机上复制该问题)。
> Task :app:lintVitalAnalyzeDevRelease
timber.lint.TimberIssueRegistry in /root/.gradle/caches/transforms-3/26daadcd46ecfc898dac002daac9b73b/transformed/jetified-timber-4.7.1/jars/lint.jar does not specify a vendor; see IssueRegistry#vendor
> Task :app:lintVitalReportDevRelease
> Task :app:lintVitalDevRelease
> Task :app:minifyDevReleaseWithR8 FAILED
ERROR: Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in /home/jenkins/workspace/APP_PR-1867/android/app/build/outputs/mapping/devRelease/missing_rules.txt.
ERROR: R8: Missing class edu.umd.cs.findbugs.annotations.SuppressFBWarnings (referenced from: void com.jwplayer.c.a.f.onMetadata(androidx.media3.common.Metadata))
Missing class kotlinx.parcelize.Parcelize (referenced from: io.didomi.sdk.Purpose and 10 other contexts)
ASM Instrumentation process wasn't able to resolve some classes, this means that
the instrumented classes might contain corrupt stack frames. Make sure the
dependencies that contain these classes are on the runtime or the provided
classpath. Otherwise, the jvm might fail to load the corrupt classes at runtime
when running in a jvm environment like unit tests.
Classes that weren't resolved:
> com.jwplayer.pub.api.configuration.PlayerConfig
> com.google.android.gms.cast.framework.CastSession
> com.jwplayer.pub.api.JWPlayer$PlayerInitializationListener
> com.jwplayer.api.b.a.l
> com.jwplayer.api.b.a.a
> com.jwplayer.c.m
> com.jwplayer.api.b.a.k
> com.jwplayer.a.a
> com.jwplayer.a.h
> com.jwplayer.c.e
-- 74 more classes --
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:minifyDevReleaseWithR8'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.R8Task$R8Runnable
> Compilation failed to complete
我尝试编辑 proguard-rules.pro 文件并添加:
-keepattributes *Annotation*
-keep @interface edu.umd.cs.findbugs.annotations.**
-keep class kotlinx.parcelize.** { *; }
-keep @kotlinx.parcelize.Parcelize class * {
<fields>;
<methods>;
}
-keep class com.jwplayer.pub.api.** { *; }
-keep class com.google.android.gms.cast.framework.** { *; }
-keep class com.jwplayer.** { *; }
但这似乎不会以任何方式影响上述错误。
我正在使用
https://github.com/jwplayer/jwplayer-react-native
app/build.gradle 的内容:
apply plugin: 'com.android.application'
apply plugin: 'org.jetbrains.kotlin.android'
apply plugin: 'com.google.firebase.firebase-perf'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
project.ext.envConfigFiles = [
dev: ".env.dev",
staging: ".env.staging",
prod: ".env.prod",
]
apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
apply plugin: 'kotlin-android'
apply plugin: "com.facebook.react"
react {
entryFile = file("../../index.js")
}
def enableSeparateBuildPerCPUArchitecture = false
def enableProguardInReleaseBuilds = true
def jscFlavor = 'org.webkit:android-jsc:+'
class BuildConfig {
static final int versionMajor = 10
static final int versionMinor = 6
static final int versionFix = 2
static final int playstoreVersionSuffix = 0
}
ext {
buildConfig = new BuildConfig()
RNJWPlayerUseGoogleCast = true
exoplayerVersion = '2.18.1'
JWPlayerVersion = '4.18.2'
}
android {
ndkVersion rootProject.ext.ndkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
compileSdkVersion rootProject.ext.compileSdkVersion
namespace "<myNameSpaceisHere>"
defaultConfig {
applicationId "<myAppIdHere>"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
// versionCode BuildConfig.versionMajor * 1000000 + 3 * 10000 + BuildConfig.versionFix * 100 + BuildConfig.playstoreVersionSuffix
versionCode BuildConfig.versionMajor * 1000000 + BuildConfig.versionMinor * 10000 + BuildConfig.versionFix * 100 + BuildConfig.playstoreVersionSuffix
versionName "${BuildConfig.versionMajor}.${BuildConfig.versionMinor}.${BuildConfig.versionFix}"
multiDexEnabled true
// react-native-iap: we only use the Google Play flavor, this needs an update if we use amazon too!!
// https://stackoverflow.com/questions/67941766/react-native-build-failed-could-not-determine-the-dependencies-of-task-appm
missingDimensionStrategy 'store', 'play'
// https://github.com/FormidableLabs/react-native-app-auth#android-setup
manifestPlaceholders = [
appAuthRedirectScheme: "<myNameSpaceisHere>"
]
// https://github.com/luggit/react-native-config#advanced-android-setup
resValue "string", "build_config_package", "<myNameSpaceisHere>"
// https://docs.wonderpush.com/docs/android-sdk#specifying-where-to-find-the-buildconfig-class
resValue "string", "wonderpush_buildConfigPackage", "<myNameSpaceisHere>"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_18
targetCompatibility JavaVersion.VERSION_18
}
kotlin {
jvmToolchain(17)
}
signingConfigs {
debug {
storeFile file('../keystore/debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
release {
storeFile file(System.getenv("APP_KEYSTORE") ?: '../keystore/debug.keystore')
storePassword System.getenv("APP") ?: 'android'
keyAlias System.getenv("APP") ?: 'androiddebugkey'
keyPassword System.getenv("APP") ?: 'android'
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
signingConfig isIdeBuild() ? signingConfigs.debug : signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds
shrinkResources enableProguardInReleaseBuilds
debuggable isIdeBuild()
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
flavorDimensions "server"
productFlavors {
dev {
dimension "server"
applicationIdSuffix ".dev"
versionNameSuffix hyphen(buildVersionNameSuffix('dev'))
buildConfigField "String", "APP_INFO", quoted(buildVersionNameSuffix("dev"))
}
staging {
dimension "server"
applicationIdSuffix ".staging"
versionNameSuffix hyphen(buildVersionNameSuffix('staging'))
buildConfigField "String", "APP_INFO", quoted(buildVersionNameSuffix("staging"))
}
prod {
dimension "server"
String branchName = System.getenv('BRANCH_NAME') ?: ""
if (isIdeBuild()) {
versionNameSuffix hyphen(buildVersionNameSuffix("prod"))
buildConfigField "String", "APP_INFO", quoted(buildVersionNameSuffix("prod"))
} else {
if (!branchName.startsWith("release/")) {
versionNameSuffix hyphen(buildVersionNameSuffix("prod"))
buildConfigField "String", "APP_INFO", quoted(buildVersionNameSuffix("prod"))
} else {
buildConfigField "String", "APP_INFO", quoted("")
}
}
}
}
// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
def apkName = "app-${variant.name}-${android.defaultConfig.versionName}-${variant.buildType.name}"
variant.outputs.each { output ->
// Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
// For each separate APK per architecture, set a unique version code as described here:
// https://developer.android.com/studio/build/configure-apk-splits.html
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
def abi = output.getFilter(com.android.build.OutputFile.ABI)
if (abi != null) { // null for the universal-debug, universal-release variants
output.versionCodeOverride =
defaultConfig.versionCode * 1000 + versionCodes.get(abi)
}
}
variant.outputs.all { output ->
outputFileName = "${apkName}.apk"
}
}
lintOptions {
baseline file("lint-baseline.xml")
checkAllWarnings true
warningsAsErrors true
}
}
def gitSha() {
if (isIdeBuild()) {
return "devbuild"
} else {
if (System.getenv("GIT_COMMIT") != null) {
return System.getenv("GIT_COMMIT").substring(0, 7)
} else {
return "devbuild"
}
}
}
def buildVersionNameSuffix(String environment) {
def upperCaseEnv = environment.toUpperCase()
if (upperCaseEnv == "PROD") {
return ""
}
return "${System.getenv('BUILD_NUMBER')}-${environment}-${gitSha()}"
}
private static quoted(string) {
return "\"$string\""
}
private static hyphen(String string) {
if (!string.isEmpty()) {
return "-$string"
} else {
return ""
}
}
dependencies {
implementation project(':react-native-config')
//noinspection GradleDynamicVersion
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.1.0'
implementation "com.google.android.gms:play-services-base:17.2.1"
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
} else {
implementation jscFlavor
}
implementation "androidx.core:core-ktx:1.2.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"
implementation 'com.dailymotion.dailymotion-sdk-android:sdk:0.2.10'
implementation 'com.jakewharton.timber:timber:4.7.1'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
testImplementation 'junit:junit:4.13'
implementation "org.jetbrains.kotlin:kotlin-test-junit:$kotlinVersion"
implementation "androidx.appcompat:appcompat:1.2.0"
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
implementation "com.google.android.gms:play-services-cast-framework:${safeExtGet('castFrameworkVersion', '+')}"
implementation 'io.didomi.sdk:android:1.86.3'
implementation "androidx.work:work-runtime:2.7.1"
// JWPlayer SDK
implementation "com.jwplayer:jwplayer-core:$JWPlayerVersion"
implementation "com.jwplayer:jwplayer-common:$JWPlayerVersion"
implementation "com.jwplayer:jwplayer-chromecast:$JWPlayerVersion"
implementation "com.jwplayer:jwplayer-ima:$JWPlayerVersion"
}
def safeExtGet(prop, fallback) {
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
build.gradle的内容:
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext {
minSdkVersion = 28
compileSdkVersion = 34
targetSdkVersion = 34
buildToolsVersion = "34.0.0"
androidXCore = "1.0.2"
androidXAnnotation = "1.2.0"
androidXBrowser = "1.3.0"
castFrameworkVersion = "21.3.0"
ndkVersion = "25.1.8937393"
kotlinVersion='1.9.10'
}
repositories {
google()
mavenCentral()
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath("com.android.tools.build:gradle")
classpath("com.facebook.react:react-native-gradle-plugin")
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath 'com.google.gms:google-services:4.4.0'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.7.1'
classpath 'com.google.firebase:perf-plugin:1.4.1'
}
}
plugins {
id "com.github.ben-manes.versions" version "0.38.0"
}
allprojects {
tasks.withType(Javadoc).all { enabled = false }
repositories {
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../node_modules/react-native/android")
}
maven {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}
mavenCentral()
mavenLocal()
google()
maven { url "https://jitpack.io" }
maven {
// JW Player
url 'https://mvn.jwplayer.com/content/repositories/releases/'
}
}
}
apply plugin: "com.facebook.react.rootproject"
dependencyUpdates.resolutionStrategy = {
componentSelection { rules ->
rules.all { ComponentSelection selection ->
boolean rejected = ['alpha', 'beta'].any { qualifier ->
selection.candidate.version ==~ /(?i).*[.-]${qualifier}[.\d-]*/
}
if (rejected) {
selection.reject('Release candidate')
}
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
def isIdeBuild() {
return properties.containsKey("android.injected.invoked.from.ide")
}
通过添加修复:
-dontwarn com.jwplayer.**
-dontwarn com.google.android.gms.cast.framework.**
-dontwarn kotlinx.parcelize.Parcelize
在
android/app/proguard-rules.pro
灵感来自:https://github.com/stripe/stripe-react-native/issues/1700#issuecomment-2298021503