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

Flutter项目模拟器运行正常,部分Android真机调用三方包时异常

解决Flutter在Android12设备上SharedPreferences/SQFlite/Path Provider的通道异常问题

问题概述

Flutter项目集成了SharedPreferences、SQFlite、Path Provider插件,在Pixel 3a/4模拟器、Android10小米Redmi 9上运行正常,但在Android12的一加Nord、三星Galaxy M33设备上触发异常:

  • SharedPreferences/Path Provider抛出:[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(channel-error, Unable to establish connection on channel., null, null)
  • SQFlite抛出:Unhandled Exception: MissingPluginException(No implementation found for method getDatabasesPath on channel com.tekartik.sqflite)

已尝试flutter clean、flutter pub get、升级依赖等操作,未解决问题。异常触发点为调用SharedPreferences.getInstance()时。

相关代码片段:
主文件初始化代码:

@override
void initState() {
  print("Init State");
  appState = Provider.of<AppState>(context, listen: false);
  initializeColors();
  super.initState();
}

void initializeColors() async {
  final fileState = Provider.of<StorageDetails>(context, listen: false);
  await fileState.initializeDirectory();
  await appState.initializeColors(); // 调用SharedPreferences初始化逻辑
}

颜色初始化文件代码:

Future<void> initializeColors() async {
  await loadColorsFromSharedPreferences();
}

Future<void> loadColorsFromSharedPreferences() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  labelColor = Color(prefs.getInt('labelColor') ?? (0xFFE7B9AA));
  accentColor = Color(prefs.getInt('accentColor') ?? (0xFFD4582F));
  labelTextColor = Color(prefs.getInt('labelTextColor') ?? (0xFF000000));
  disabledButtonColor = Color(prefs.getInt('disabledButtonColor') ?? (0xFFD9D9D9));
  appTheme = prefs.getInt('appTheme') ?? 0;

  if (appTheme == 1) {
    setDarkTheme();
    print('DarkThemeSet');
  } else {
    setLightTheme();
    print('LightThemeSet');
  }
}

核心原因

  1. Android12+包可见性限制:Android12及以上系统默认启用包可见性规则,应用无法直接访问其他第三方包或系统组件,导致Flutter插件与原生通道无法建立连接。
  2. 初始化时机不当:在Widget未完全挂载时调用原生插件方法,可能导致通道初始化未完成就触发调用。
  3. 构建缓存残留:旧的原生构建缓存可能导致插件注册信息未正确更新。

优雅解决方案

1. 配置Android包可见性

在android/app/src/main/AndroidManifest.xml中添加<queries>标签,声明应用需要访问的组件,确保Flutter插件能正常与原生通信:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 其他现有配置 -->
    <queries>
        <!-- 允许访问Android核心应用组件,适配Flutter插件通道 -->
        <intent>
            <action android:name="android.intent.action.MAIN"/>
        </intent>
    </queries>
    <!-- 其他现有配置 -->
</manifest>

2. 调整初始化时机

修改主文件的initState方法,使用WidgetsBinding.instance.addPostFrameCallback延迟初始化操作,确保Widget树完全构建后再调用原生插件:

@override
void initState() {
  super.initState();
  print("Init State");
  appState = Provider.of<AppState>(context, listen: false);
  // 延迟到Widget构建完成后执行异步初始化
  WidgetsBinding.instance.addPostFrameCallback((_) {
    initializeColors();
  });
}

void initializeColors() async {
  final fileState = Provider.of<StorageDetails>(context, listen: false);
  await fileState.initializeDirectory();
  await appState.initializeColors();
}

3. 彻底清理并重建项目

执行以下步骤清除残留缓存,确保插件正确注册:

  • 运行flutter clean
  • 删除android/app/build目录
  • 运行flutter pub get
  • 重新构建项目:flutter run --debug

4. 锁定兼容的插件版本

避免盲目升级所有依赖,选择支持Android12的稳定版本,修改pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.2.2
  sqflite: ^2.3.0
  path_provider: ^2.1.1
  provider: ^6.1.1

执行flutter pub get更新依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 17:45:54