You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Relocation/Shadow解决React Native重复类错误?

解决React Native包中com.realsil.sdk.*重复类冲突方案

核心思路

针对IDO和CRP SDK重复的com.realsil.sdk.*类,使用Shadow插件对其中一个SDK的重复类进行包路径重定位,避免类冲突。以下是具体Gradle配置修改步骤:

1. 正确应用Shadow插件

在build.gradle中添加Shadow插件应用(仅在rootProject的buildscript中添加classpath不够,需单独应用插件):

apply plugin: 'com.android.library'
apply plugin: 'maven-publish'
apply plugin: 'com.github.johnrengelman.shadow' // 新增这行

2. 配置类重定位规则

在android块之后添加Shadow插件配置,指定要重定位的包路径(以CRP SDK为例,将其com.realsil.sdk.*重命名为com.crp.realsil.sdk.*):

shadowJar {
    // 重定位CRP SDK中的重复包
    relocate 'com.realsil.sdk', 'com.crp.realsil.sdk'
    // 仅处理CRP相关依赖,避免影响其他库
    configurations = [project.configurations.crpShadow]
}

// 创建单独配置用于Shadow处理
configurations {
    crpShadow
    customConfig.extendsFrom implementation
}

3. 调整依赖配置

将CRP SDK的implementation改为crpShadow配置,确保Shadow插件只处理该依赖:

dependencies {
    // ... 其他依赖保持不变
    
    // CRP -- SDK--need 修改依赖配置
    crpShadow fileTree(dir: 'libs/crpblesdk', include: ['*.aar', '*.jar'], exclude: [])
    // 将处理后的Shadow jar加入implementation
    implementation shadowJar
}

4. 适配Android库变体

在afterEvaluate块中添加代码,关联Shadow任务与Android库变体构建流程:

afterEvaluate { project ->
    // ... 原有代码保持不变
    
    // 确保Shadow任务在变体编译前执行
    android.libraryVariants.all { variant ->
        variant.javaCompileProvider.get().dependsOn(shadowJar)
    }
}

完整修改后的关键代码片段

def DEFAULT_COMPILE_SDK_VERSION = 31
def DEFAULT_BUILD_TOOLS_VERSION = '28.0.3'
def DEFAULT_MIN_SDK_VERSION = 23
def DEFAULT_TARGET_SDK_VERSION = 31

def safeExtGet(prop, fallback) {
    rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}

def safeExtHasProp(prop){
    rootProject.ext.has(prop)
}

apply plugin: 'com.android.library'
apply plugin: 'maven-publish'
apply plugin: 'com.github.johnrengelman.shadow' // 新增

buildscript {
  
    if (project == rootProject) {
        repositories {
            google()
            jcenter()
            maven {
                url = uri("https://plugins.gradle.org/m2/")
            }
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.5.4'
            classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1"
            classpath "com.github.johnrengelman:shadow:8.1.0"
        }
    }
}

android {
    compileSdkVersion safeExtGet('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
    buildToolsVersion safeExtGet('buildToolsVersion', DEFAULT_BUILD_TOOLS_VERSION)
    defaultConfig {
        minSdkVersion safeExtGet('minSdkVersion', DEFAULT_MIN_SDK_VERSION)
        targetSdkVersion safeExtGet('targetSdkVersion', DEFAULT_TARGET_SDK_VERSION)
        versionCode 1
        versionName "1.0"
        multiDexEnabled true

        ndk {
            abiFilters "arm64-v8a", "armeabi-v7a", "x86", "x86_64"
        }
    }
    lintOptions {
        abortOnError false
    }
    sourceSets {
        main {
            assets.srcDirs = ['assets']
        }
    }
    compileOptions {
        coreLibraryDesugaringEnabled true
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

// Shadow插件配置
shadowJar {
    relocate 'com.realsil.sdk', 'com.crp.realsil.sdk'
    configurations = [project.configurations.crpShadow]
}

configurations {
    crpShadow // 新增配置
    customConfig.extendsFrom implementation
}

repositories {
    mavenLocal()
    maven {
        url "$rootDir/../node_modules/react-native/android"
    }
    maven {
        url "$rootDir/../node_modules/jsc-android/dist"
    }
    google()
    jcenter()
}

dependencies {
    implementation 'com.facebook.react:react-native:+'

    implementation 'org.greenrobot:greendao:3.2.2'
    implementation 'com.alibaba:fastjson:1.2.35'
    implementation 'com.squareup.okhttp3:okhttp:3.4.1'
    implementation 'com.squareup.okio:okio:1.9.0'
    implementation 'com.google.code.gson:gson:2.8.0'
    implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
    implementation 'com.tencent.bugly:crashreport:latest.release'

    //KCT -- SDK--need
    implementation fileTree(dir: 'libs/kctblesdk', include: ['*.aar', '*.jar'], exclude: [])

    //IDO -- SDK--need
    implementation fileTree(dir: 'libs/idoblesdk', include: ['*.jar'], exclude: [])

    //SMA -- SDK--need
    debugImplementation fileTree(dir: 'libs/smablesdk/debug', include: ['*.aar', '*.jar'], exclude: [])
    releaseImplementation fileTree(dir: 'libs/smablesdk/release', include: ['*.aar', '*.jar'], exclude: [])

    //CRP -- SDK--need 修改依赖配置
    crpShadow fileTree(dir: 'libs/crpblesdk', include: ['*.aar', '*.jar'], exclude: [])
    implementation shadowJar // 加入处理后的jar

    if(safeExtHasProp('iotLibsVersion')){
        implementation fileTree(dir: 'libs/smablesdk/iot_libs', include: ['*.aar', '*.jar'], exclude: [])
        implementation group: 'com.adups.iot', name: 'trace', version: '1.0.4'
        implementation group: 'com.adups.iot', name: 'mqtt_libs', version: '1.1.3'
        implementation group: 'com.adups.iot', name: 'iot_download_libs', version: '1.1.7'
        implementation group: 'com.adups.iot', name: 'http_libs', version: '1.0.8'
    }

    implementation 'no.nordicsemi.android:dfu:1.8.1'

    def room_version = "2.4.1"
    implementation "androidx.room:room-runtime:$room_version"
    annotationProcessor "androidx.room:room-compiler:$room_version"
    implementation "androidx.room:room-rxjava2:$room_version"
    implementation "androidx.room:room-guava:$room_version"
    testImplementation "androidx.room:room-testing:$room_version"

    def work_version = "2.7.0"
    implementation "androidx.work:work-runtime:$work_version"

    implementation 'com.google.android.gms:play-services-location:19.0.1'
    implementation 'com.google.android.gms:play-services-maps:18.0.2'
    coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.1"
}

def configureReactNativePom(def pom) {
    def packageJson = new groovy.json.JsonSlurper().parseText(file('../package.json').text)

    pom.project {
        name packageJson.title
        artifactId packageJson.name
        version = packageJson.version
        group = "com.reactlibrary"
        description packageJson.description
        url packageJson.repository.baseUrl

        licenses {
            license {
                name packageJson.license
                url packageJson.repository.baseUrl + '/blob/master/' + packageJson.licenseFilename
                distribution 'repo'
            }
        }

        developers {
            developer {
                id packageJson.author.username
                name packageJson.author.name
            }
        }
    }
}

afterEvaluate { project ->
    task androidJavadoc(type: Javadoc) {
        source = android.sourceSets.main.java.srcDirs
        classpath += files(android.bootClasspath)
        classpath += files(project.getConfigurations().getByName('customConfig').asList())
        include '**/*.java'
    }

    task androidJavadocJar(type: Jar, dependsOn: androidJavadoc) {
        classifier = 'javadoc'
        from androidJavadoc.destinationDir
    }

    task androidSourcesJar(type: Jar) {
        classifier = 'sources'
        from android.sourceSets.main.java.srcDirs
        include '**/*.java'
    }

    android.libraryVariants.all { variant ->
        def name = variant.name.capitalize()
        def javaCompileTask = variant.javaCompileProvider.get()

        task "jar${name}"(type: Jar, dependsOn: javaCompileTask) {
            from javaCompileTask.destinationDir
        }
        // 关联Shadow任务与变体编译
        javaCompileTask.dependsOn(shadowJar)
    }

    artifacts {
        archives androidSourcesJar
        archives androidJavadocJar
    }

    publishing {
        repositories {
            maven {
                url = uri("${rootProject.projectDir}/maven-repo")
            }
        }
    }
}

验证执行

运行构建命令检查是否解决冲突:

./gradlew assembleRelease

内容的提问来源于stack exchange,提问作者Joao Victor Simonassi Farias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 03:44:57