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

动态特性模块中NotificationService发布后ClassNotFoundException问题求助

动态特性模块中NotificationService的ClassNotFoundException问题

问题描述

我在动态特性模块(DFM)中声明了多个Service类,应用发布到Google Play商店后,部分用户后台出现仅针对NotificationService的java.lang.ClassNotFoundException异常(通过Crashlytics统计)。涉及设备包括Oppo(Android 12)、Lenovo(Android 10)、Samsung(Android 11),应用minSdk版本为21。

已排查APK确认该类存在,将Manifest中的类名改为绝对路径后,调试版本、应用分享版本及内部测试版本均无异常,但正式发布后仍出现该问题。

异常栈

Fatal Exception: java.lang.RuntimeException: Unable to create NotificationService: java.lang.ClassNotFoundException: Didn't find class on path: DexPathList
       at android.app.ActivityThread.handleCreateService(ActivityThread.java:4668)
       at android.app.ActivityThread.access$100(ActivityThread.java:254)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2203)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:233)
       at android.os.Looper.loop(Looper.java:344)
       at android.app.ActivityThread.main(ActivityThread.java:8212)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)

Caused by java.lang.ClassNotFoundException: Didn't find class NotificationService on path: DexPathList
       at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
       at android.app.AppComponentFactory.instantiateService(AppComponentFactory.java:129)
       at androidx.core.app.CoreComponentFactory.instantiateService(CoreComponentFactory.java:75)
       at android.app.ActivityThread.handleCreateService(ActivityThread.java:4637)
       at android.app.ActivityThread.access$100(ActivityThread.java:254)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2203)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:233)
       at android.os.Looper.loop(Looper.java:344)
       at android.app.ActivityThread.main(ActivityThread.java:8212)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)

Manifest配置

<service
    android:name=".NotificationService"
    android:exported="true"
    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
    <intent-filter>
        <action android:name="android.service.notification.NotificationListenerService" />
    </intent-filter>
</service>

build.gradle配置(动态模块)

plugins {
    id 'com.android.dynamic-feature'
    id 'org.jetbrains.kotlin.android'
    id 'kotlin-android'
    id 'kotlin-kapt'
    id 'kotlin-platform-android'
    id 'kotlin-parcelize'
    id 'com.google.gms.google-services'
    id 'com.google.firebase.crashlytics'
}
android {
    compileSdk 31

    defaultConfig {
        minSdk 21
    }

    buildFeatures {
        viewBinding = true
        dataBinding = true
    }
    buildTypes {
        debug {
            debuggable true
        }
        release {
            debuggable false
            minifyEnabled false
        }
    }
    flavorDimensions "default"
    productFlavors {
        dev {
            dimension = 'default'
        }
        prod {
            dimension = 'default'
        }
    }
    compileOptions {
        targetCompatibility JavaVersion.VERSION_1_8
        sourceCompatibility JavaVersion.VERSION_1_8
    }
    packagingOptions {
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/CHANGES'
        exclude 'META-INF/README.md'
        exclude 'META-INF/*'
    }

    kotlinOptions {
        jvmTarget = '1.8'
    }
    configurations.all {
        resolutionStrategy {
            exclude group: "org.jetbrains.kotlinx", module: "kotlinx-coroutines-debug"
            exclude group: "com.squareup.okio"
            exclude group: "com.squareup.picasso"
        }
    }
    defaultConfig {
        testInstrumentationRunnerArguments clearPackageData: 'true'
        vectorDrawables.useSupportLibrary = true
    }
    testOptions {
        unitTests.returnDefaultValues = true
    }
    sourceSets {
        main {
            aidl {
                srcDirs 'src/main/aidl'
            }
        }
    }
}

解决方案

1. 核心方案:迁移Service到基础模块

NotificationListenerService是系统主动绑定的服务,系统会在需要时直接尝试创建该类,而动态特性模块可能还未完成下载或加载,这是最根本的原因。将NotificationService从动态模块迁移到base模块,确保系统启动时就能找到该类。

2. 若必须保留在动态模块的处理

如果因业务需求无法迁移,尝试以下方案:

  • 设置动态模块为安装时交付:在动态模块的build.gradle中修改默认配置,强制模块随主应用一起安装,而非按需下载:
    android {
        defaultConfig {
            deliveryType "install-time"
        }
    }
    
  • 使用完整类路径:将Manifest中android:name改为绝对路径,例如com.your.package.NotificationService,避免相对路径的解析歧义。
  • 提前触发模块加载:在应用启动时主动调用SplitInstallManager下载并安装该动态模块,确保Service可用后再允许系统绑定。

3. 验证Google Play拆分规则

登录Google Play Console,检查APK拆分配置,确保包含NotificationService的Dex文件被正确包含到所有目标设备的APK变体中,避免因拆分规则导致部分设备缺失该类。

4. 厂商适配

针对Oppo、Samsung等厂商设备,测试正式签名包的动态模块加载逻辑,部分厂商系统对动态模块的类加载有特殊限制,可能需要额外的初始化逻辑确保类路径正确。

内容的提问来源于stack exchange,提问作者user20429506

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 14:55:15