集成FlutterDownloader与FlutterLocalNotifications后应用启动崩溃排查
问题
在尝试运行集成了FlutterDownloader和FlutterLocalNotifications插件的Flutter应用时遭遇启动崩溃,已附上gradle配置文件与AndroidManifest.xml文件。
崩溃错误信息
E/AndroidRuntime(10309): FATAL EXCEPTION: main E/AndroidRuntime(10309): Process: com.example.task1, PID: 10309 E/AndroidRuntime(10309): java.lang.NoSuchMethodError: No interface method addWindowLayoutInfoListener(Landroid/app/Activity;Lj$/util/function/Consumer;)V in class Landroidx/window/ex tensions/layout/WindowLayoutComponent; or its super classes (declaration of 'androidx.window.extensions.layout.WindowLayoutComponent' appears in /system_ext/framework/androidx.window.extensions.jar) E/AndroidRuntime(10309): at androidx.window.layout.ExtensionWindowLayoutInfoBackend.registerLayoutChangeCallback(ExtensionWindowLayoutInfoBackend.kt:68) E/AndroidRuntime(10309): at androidx.window.layout.WindowInfoTrackerImpl$windowLayoutInfo$1.invokeSuspend(WindowInfoTrackerImpl.kt:52) E/AndroidRuntime(10309): at androidx.window.layout.WindowInfoTrackerImpl$windowLayoutInfo$1.invoke(Unknown Source:8) E/AndroidRuntime(10309): at androidx.window.layout.WindowInfoTrackerImpl$windowLayoutInfo$1.invoke(Unknown Source:4) E/AndroidRuntime(10309): at kotlinx.coroutines.flow.SafeFlow.collectSafely(Builders.kt:61) E/AndroidRuntime(10309): at kotlinx.coroutines.flow.AbstractFlow.collect(Flow.kt:212) E/AndroidRuntime(10309): at androidx.window.java.layout.WindowInfoTrackerCallbackAdapter$addListener$1$1.invokeSuspend(WindowInfoTrackerCallbackAdapter.kt:96) E/AndroidRuntime(10309): at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) E/AndroidRuntime(10309): at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) E/AndroidRuntime(10309): at android.os.Handler.handleCallback(Handler.java:958) E/AndroidRuntime(10309): at android.os.Handler.dispatchMessage(Handler.java:99) E/AndroidRuntime(10309): at android.os.Looper.loopOnce(Looper.java:205) E/AndroidRuntime(10309): at android.os.Looper.loop(Looper.java:294) E/AndroidRuntime(10309): at android.app.ActivityThread.main(ActivityThread.java:8177)
android\build.gradle 配置
buildscript { repositories { google() mavenCentral() gradlePluginPortal() } dependencies { classpath 'com.android.tools.build:gradle:7.3.1' classpath "com.android.tools.build:gradle:7.4.2" classpath "org.jlleitschuh.gradle:ktlint-gradle:11.5.0" } } rootProject.allprojects { repositories { google() mavenCentral() } } apply plugin: "com.android.library" apply plugin: "kotlin-android" apply plugin: "org.jlleitschuh.gradle.ktlint" rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" } subprojects { project.evaluationDependsOn(':app') } android { namespace 'com.example.task1' compileSdk 34 compileOptions { coreLibraryDesugaringEnabled true sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } sourceSets { main.java.srcDirs += "src/main/kotlin" } defaultConfig { multiDexEnabled true minSdkVersion 16 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } lintOptions { disable 'InvalidPackage' } } dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.2' implementation "androidx.core:core:1.3.0" implementation "androidx.media:media:1.1.0" implementation "com.google.code.gson:gson:2.8.9" implementation "androidx.work:work-runtime:2.7.1" implementation "androidx.annotation:annotation:1.5.0" implementation "androidx.core:core-ktx:1.9.0" }
app\build.gradle 配置
plugins { id "com.android.application" id "kotlin-android" id "dev.flutter.flutter-gradle-plugin" } def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } android { namespace "com.example.task1" compileSdk 34 ndkVersion flutter.ndkVersion compileOptions { // Flag to enable support for the new language APIs coreLibraryDesugaringEnabled true // Sets Java compatibility to Java 8 sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } sourceSets { main.java.srcDirs += 'src/main/kotlin' } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.task1" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. minSdkVersion flutter.minSdkVersion targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName multiDexEnabled true } dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.2' } buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } } }
AndroidManifest.xml 配置
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <application android:label="task1" android:name="${applicationName}" android:icon="@mipmap/ic_launcher"> <provider android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider" android:authorities="${applicationId}.flutter_downloader.provider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths"/> </provider> <!-- Begin FlutterDownloader customization --> <!-- disable default Initializer --> <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <meta-data android:name="androidx.work.WorkManagerInitializer" android:value="androidx.startup" tools:node="remove" /> </provider> <!-- declare customized Initializer --> <provider android:name="vn.hunghd.flutterdownloader.FlutterDownloaderInitializer" android:authorities="${applicationId}.flutter-downloader-init" android:exported="false"> <!-- changes this number to configure the maximum number of concurrent tasks --> <meta-data android:name="vn.hunghd.flutterdownloader.MAX_CONCURRENT_TASKS" android:value="5" /> </provider> <!-- End FlutterDownloader customization --> <activity android:name=".MainActivity" android:exported="true" android:showWhenLocked="true" android:turnScreenOn="true" android:launchMode="singleTop" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize"> <!-- Specifies an Android theme to apply to this Activity as soon as the Android process has started. This theme is visible to the user while the Flutter UI initializes. After that, this theme continues to determine the Window background behind the Flutter UI. --> <meta-data android:name="io.flutter.embedding.android.NormalTheme" android:resource="@style/NormalTheme" /> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <!-- Don't delete the meta-data below. This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> <meta-data android:name="flutterEmbedding" android:value="2" /> <receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" /> <receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/> <action android:name="android.intent.action.QUICKBOOT_POWERON" /> <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/> </intent-filter> </receiver> <receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ActionBroadcastReceiver" /> </application> <!-- Required to query activities that can process text, see: https://developer.android.com/training/package-visibility?hl=en and https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT. In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. --> <queries> <intent> <action android:name="android.intent.action.PROCESS_TEXT"/> <data android:mimeType="text/plain"/> </intent> </queries> <queries> <intent> <action android:name="android.intent.action.VIEW" /> </intent> </queries> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> <uses-permission android:name="android.permission.USE_EXACT_ALARM" /> <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> </manifest>
请问是否是权限处理或gradle/manifest文件存在错误?
解决方案
这个崩溃是androidx.window库版本不兼容导致的,和权限关系不大,主要是gradle配置里的依赖冲突和版本问题:
1. 修复gradle插件版本冲突
在android\build.gradle的buildscript.dependencies里,同时声明了两个不同版本的Android Gradle插件,这会引发依赖冲突。删除其中一个,建议保留更高版本:
// 保留这一行,删除7.3.1的声明 classpath "com.android.tools.build:gradle:7.4.2"
2. 锁定androidx.window库的版本
崩溃日志里的NoSuchMethodError是因为应用依赖的androidx.window库版本与系统内置的扩展库不兼容。在android\build.gradle的dependencies中添加统一版本的依赖:
dependencies { // 其他依赖保持不变 implementation "androidx.window:window:1.0.0" implementation "androidx.window:window-java:1.0.0" }
或者通过强制解析策略统一版本,避免插件引入不同版本:
configurations.all { resolutionStrategy.force "androidx.window:window:1.0.0" resolutionStrategy.force "androidx.window:window-java:1.0.0" }
3. 统一androidx.core依赖版本
当前androidx.core依赖存在版本不一致问题:
androidx.core:core:1.3.0androidx.core:core-ktx:1.9.0
统一升级到相同的稳定版本,例如:
implementation "androidx.core:core:1.12.0" implementation "androidx.core:core-ktx:1.12.0"
4. 清理缓存并重新构建
完成上述修改后,执行以下命令清理缓存并重新构建:
flutter clean cd android && ./gradlew clean cd .. && flutter pub get flutter run
补充说明
- AndroidManifest中的权限配置符合插件要求,无需修改;
- FlutterDownloader和FlutterLocalNotifications的Manifest配置正确,不存在问题;
- 该问题常见于部分定制ROM的
androidx.window.extensions库版本较低,与应用依赖的高版本库不兼容,锁定版本即可解决。
内容的提问来源于stack exchange,提问作者Bhadraksh Bhargava
相关产品推荐
相关产品推荐

