flutter 报错 插件未注册 Unhandled Exception: MissingPluginException(No implementation f

7,417 阅读4分钟

最近把 老的项目重新跑起来,无论如何都不能跑起来,折腾了好几天,记录一下心路历程,都是坑! 满满干货

android studio 运行老项目

  1. 不能识别flutter版本

E/flutter (14355): [ERROR:flutter/shell/common/shell.cc(242)] Dart Error: Can't load Kernel binary: Invalid kernel binary: Indicated size is invalid. E/flutter (14355): [ERROR:flutter/runtime/dart_isolate.cc(169)] Could not prepare isolate. E/flutter (14355): [ERROR:flutter/runtime/runtime_controller.cc(401)] Could not create root isolate. E/flutter (14355): [ERROR:flutter/shell/common/shell.cc(571)] Could not launch engine with configuration.

杀掉进程,重启项目就可以

2.神坑的问题 报错插件未注册

I/flutter (17872): [INFO] J: Serving on 0.0.0.0:55588
E/flutter (17872): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences)
E/flutter (17872): 
E/flutter (17872): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences)
E/flutter (17872):

报错 shared_preferences 插件注册没成功

可以尝试

flutter clean flutter pub get/ flutter packages get

不行,往下看: 参照网上的资料

1.shared_preferences 0.2.4及更高版本,可直接在flutter项目的main方法中添加以下内容

import 'package:shared_preferences/shared_preferences.dart';
void main() {
  SharedPreferences.setMockInitialValues({});
  runApp(MyApp());
}

对于早期版本,可以改为:

const MethodChannel('plugins.flutter.io/shared_preferences')
.setMockMethodCallHandler((MethodCall methodCall) async { 
    if (methodCall.method == 'getAll') { 
        return <String, dynamic>{}; // set initial values here if desired 
    } 
    return null; 
});

上面这个方法 确实能进入项目,能解决此问题,但是有两个问题 1.如果是项目中如果采用webView,跳转webView 页面会报错,项目报错 path_provider 未注册,2. 每次重启之前保存的数据都没了,实际的项目中肯定是不行的,用户每次进入APP 都是需要重新登录。

如果是没有报错其他的插件未注册,可以试试:

flutter pub cache repair

上述所有的方法不能解决问题,中间尝试了很多方法,还是不能不能解决问题,尝试了升级flutter版本,尝试改动android源码均不能解决这个问题。

网上查找资料无意中看到一句话,flutter项目如果有一个插件有问题,会导致其他的插件注册也会不成功。 无意中看到希望的曙光!

开始新建一个项目,跑最简单的闭环,思路是把原项目的依赖都安装了

以下是我这个项目的 pubspec.yaml文件 插件依赖部分

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  dio: ^3.0.10
  provider: ^4.3.2+3
  rxdart: ^0.25.0
  cookie_jar: ^1.0.1
  dio_cookie_manager: ^1.0.0
  flutter_screenutil: ^4.0.2+3
  fluro: ^1.7.8
  shared_preferences: ^2.0.0
  crypto: ^2.1.5
  logger: ^0.9.4
  webview_flutter:
    path: plugins/webview_flutter
  # webview_flutter: ^2.0.8
  jaguar: ^2.4.46
  jaguar_flutter_asset: ^2.2.0
  fluwx_no_pay: ^2.4.0+1
  permission_handler: ^5.0.1+1
  flutter_easyloading: ^2.2.2
  get_it: ^5.0.3
  image_picker: ^0.6.7+20
  contacts_service: ^0.4.6
  path_provider: ^2.0.0
  package_info: ^0.4.3+2
  device_info: ^1.0.0
  circular_check_box: ^1.0.4
  flutter_bloc: ^6.1.1
  equatable: ^1.2.5
  flutter_aliyun_captcha: ^1.0.1
  flutter_channel: ^0.0.1
  uuid: ^2.2.2
  store_redirect: ^1.0.2
  open_file: ^3.0.3
  tpns_flutter_plugin:
    path: plugins/TPNS-Flutter-Plugin
  flutter_picker: ^1.1.0
  barcode_scan: ^1.0.0
  # amap_flutter_location: ^2.0.0
#  amap_location_muka: ^0.1.1
  jwt_decoder: ^2.0.1

然后main.dart 文件

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
// import 'package:uuid/uuid.dart';

void main() {
  runApp(MyApp());
  initUuid();
}

void initUuid() async {
  SharedPreferences _prefs = await SharedPreferences.getInstance();
 
}

步骤是 pubspec.yaml 依赖插件全部注释,再flutter clean ,flutter pub get 启动项目,再逐个放开执行此过程,终于定位到当放开 amap_location_muka: ^0.1.1 这个插件的时候,就会看到开头说的报错,至此终于定位到问题了,flutter这个机制实在是坑!

最后 我换成下面这个插件

amap_location_fluttify: ^0.20.0
原文例子如下:

/// !注意: 只要是返回Future的方法, 一律使用`await`修饰, 确保当前方法执行完成后再执行下一行, 在不能使用`await`修饰的环境下, 在`then`方法中执行下一步.
/// 初始化 iOS在init方法中设置, android需要去AndroidManifest.xml里去设置, 详见 https://lbs.amap.com/api/android-sdk/gettingstarted
await AmapCore.init('ios key');

// 单次定位
if (await requestPermission()) {
  final location = await AmapLocation.fetchLocation();
  setState(() => _location = location);
}

// 连续定位
if (await requestPermission()) {
  AmapLocation.listenLocation()
    .listen((location) => setState(() => _location = location));
}

因为我的项目是webView链接远端的h5项目,基本的业务都是h5上面的,所以flutter这里只需要某个时刻单词定位就可以了,利用flutter定位的经纬度,传入到h5项目中,h5项目也引入了web的高德地图(这里有坑,vue的移动端项目,没有对应的高德地图的插件,自己手撸了一个两个组件,一个是定位的,一个是可以输入地图检索位置,如果有谁需要看实现可以私聊我)

下面是flutter 调用定位(配置高德key我会写一篇,附带安卓签名)

Future<Map<String, dynamic>> _getLocation(data) async  {
  await AmapLocation.instance.init(iosKey: ''); //https://console.amap.com/dev/key/app 去配置项目的key

  // return null; // 用于调试
    if (Platform.isAndroid
        ? await Permission.location.isPermanentlyDenied
        : await Permission.location.isDenied) {
      DialogUtil.buildDialog(context, S.of(context).permissionTitle,
          S.of(context).locationPermissionDesc, openAppSettings);
      return {"permission": false};
    }
    if (await Permission.locationWhenInUse.request().isGranted) {
      try {
        Location _location = await AmapLocation.instance.fetchLocation();
        Map locationMap = <String, dynamic> {
          "address" : _location.address,
          "latitude" : _location.latLng.latitude,
          "longitude":   _location.latLng.longitude
        };
        // print(_location.toJson());
        final res = <String, dynamic>{
          "api": "getLocation",
          "data": locationMap
        };
        _controller.then((v) => v.evaluateJavascript(
            "window.jsBridge.receiveMessage(${json.encode(res)})")); //与嵌套的h5页面通信
        //停止定位
        // if (await Permission.locationWhenInUse.request().isGranted) {
        //   await AmapLocation.instance.stopLocation();
        // }
        return res;
      }catch(e){
        DialogUtil.buildToast(e);// toast 提示,这里是DialogUtil自己封装的提示插件
      }

    } else {
      DialogUtil.buildToast(S.of(context).contactPermission); // toast 提示
    }
}

我看了网上很多的资料flutter webview 与 web项目通信,讲的很简单,实际项目肯定需要一套对应的中间桥接插件,但是这个就没有,如果是有对flutter 和 web页面通信有疑问的,我可以单独写一篇文章。

原文 有道云笔记:note.youdao.com/s/deIDli2G