当我使用floor数据库时,出现了“MissingPluginException(在通道com.tekartik.sqflite上找不到getDatabasesPath方法的实现)”错误。

15

我正在尝试使用floor数据库,但是当我想要构建数据库时,我遇到了以下错误

E/flutter (26007): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: MissingPluginException(No implementation found for method getDatabasesPath on channel com.tekartik.sqflite)
E/flutter (26007): #0      MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:154:7)
E/flutter (26007): <asynchronous suspension>
E/flutter (26007): #1      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:329:12)
E/flutter (26007): #2      invokeMethod (package:sqflite/src/sqflite_impl.dart:17:13)
E/flutter (26007): #3      SqfliteDatabaseFactoryImpl.invokeMethod (package:sqflite/src/factory_impl.dart:82:7)
E/flutter (26007): #4      SqfliteDatabaseFactoryMixin.safeInvokeMethod.<anonymous closure> (package:sqflite_common/src/factory_mixin.dart:25:35)
E/flutter (26007): #5      wrapDatabaseException (package:sqflite/src/exception_impl.dart:7:32)
E/flutter (26007): #6      SqfliteDatabaseFactoryImpl.wrapDatabaseException (package:sqflite/src/factory_impl.dart:78:7)
E/flutter (26007): #7      SqfliteDatabaseFactoryMixin.safeInvokeMethod (package:sqflite_common/src/factory_mixin.dart:25:7)
E/flutter (26007): #8      SqfliteDatabaseFactoryMixin.getDatabasesPath (package:sqflite_common/src/factory_mixin.dart:143:26)
E/flutter (26007): #9      getDatabasesPath (package:sqflite/sqflite.dart:168:54)
E/flutter (26007): #10     DatabaseFactoryExtension.getDatabasePath (package:floor/src/sqflite_database_factory.dart:23:23)
E/flutter (26007): #11     _$AppDatabaseBuilder.build (package:fluttermiwallet/db/database.g.dart:46:40)
E/flutter (26007): #12     main (package:fluttermiwallet/main.dart:9:67)
E/flutter (26007): #13     _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:241:25)
E/flutter (26007): #14     _rootRun (dart:async/zone.dart:1184:13)
E/flutter (26007): #15     _CustomZone.run (dart:async/zone.dart:1077:19)
E/flutter (26007): #16     _runZoned (dart:async/zone.dart:1619:10)
E/flutter (26007): #17     runZonedGuarded (dart:async/zone.dart:1608:12)
E/flutter (26007): #18     _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:233:5)
E/flutter (26007): #19     _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
E/flutter (26007): #20     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

我的 Flutter 版本:

Flutter 1.17.5 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 8af6b2f038 (13 days ago) • 2020-06-30 12:53:55 -0700
Engine • revision ee76268252
Tools • Dart 2.8.4

floor、floor_generator和build_runner的版本如下:

environment:
  sdk: ">=2.7.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^0.1.3
  floor: ^0.13.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  floor_generator: ^0.13.0
  build_runner: ^1.7.3

main.dart 文件中,我使用 $FloorAppDatabase 构建我的数据库:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  var db = await $FloorAppDatabase.databaseBuilder('mydb.db').build();
  runApp(MyApp(db));
}

在android文件夹中,GeneratedPluginRegistrant.java文件:

package io.flutter.plugins;

import androidx.annotation.Keep;
import androidx.annotation.NonNull;

import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.plugins.shim.ShimPluginRegistry;

/**
 * Generated file. Do not edit.
 * This file is generated by the Flutter tool based on the
 * plugins that support the Android platform.
 */
@Keep
public final class GeneratedPluginRegistrant {
  public static void registerWith(@NonNull FlutterEngine flutterEngine) {
    ShimPluginRegistry shimPluginRegistry = new ShimPluginRegistry(flutterEngine);
      io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin.registerWith(shimPluginRegistry.registrarFor("io.flutter.plugins.flutter_plugin_android_lifecycle.FlutterAndroidLifecyclePlugin"));
    flutterEngine.getPlugins().add(new io.flutter.plugins.imagepicker.ImagePickerPlugin());
    flutterEngine.getPlugins().add(new io.flutter.plugins.pathprovider.PathProviderPlugin());
    flutterEngine.getPlugins().add(new io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin());
    flutterEngine.getPlugins().add(new com.tekartik.sqflite.SqflitePlugin());
  }
}

以及MainActivity.kt文件:

import android.os.Bundle
import io.flutter.app.FlutterActivity
import io.flutter.plugins.imagepicker.ImagePickerPlugin


class MainActivity : FlutterActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ImagePickerPlugin.registerWith(
                registrarFor("io.flutter.plugins.imagepicker.ImagePickerPlugin"))

    }

}
11个回答

33

由于新增依赖关系,这种情况发生了,在我的情况下,以下命令可行。转到终端,然后

flutter clean

重新运行项目


1
这解决了我的相同问题 <3 - Abdullah Bahattab
1
这也解决了我的问题。 - daydreamer

13

当我试图在Chrome中运行我的sqflite应用时,我遇到了这个错误。当然,sqflite不支持Web,所以我不应该惊讶它会抛出一个错误!在移动模拟器(或macOS)上运行应该可以解决问题。


11

我终于找到了答案。我必须在我的 MainActivity 中添加 Sqflite 插件:SqflitePlugin.registerWith(registrarFor("com.tekartik.sqflite.SqflitePlugin"))

我的 MainActivity 更改如下:

import android.os.Bundle
import io.flutter.app.FlutterActivity
import io.flutter.plugins.imagepicker.ImagePickerPlugin
import com.tekartik.sqflite.SqflitePlugin


class MainActivity : FlutterActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ImagePickerPlugin.registerWith(
                registrarFor("io.flutter.plugins.imagepicker.ImagePickerPlugin"))
        SqflitePlugin.registerWith(registrarFor("com.tekartik.sqflite.SqflitePlugin"))

    }

}


11
现在出现错误:Unresolved reference: registrarFor。如何解决? - Raines

10
flutter clean
flutter run

这对我起作用了。


7

如果你只在发布版本中遇到此问题,则可以使用Proguard规则构建发布应用程序。

    buildTypes {
        release {
            signingConfig signingConfigs.debug
            minifyEnabled true
            useProguard true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

在目录android/app/中创建一个名为proguard-rules.pro的文件,并在其中编写以下内容:
#Flutter Wrapper
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.**  { *; }
-keep class io.flutter.util.**  { *; }
-keep class io.flutter.view.**  { *; }
-keep class io.flutter.**  { *; }
-keep class io.flutter.plugins.**  { *; }
-keep class androidx.lifecycle.DefaultLifecycleObserver

这是唯一对我起作用的东西!谢谢!你刚刚救了我的一天。虽然我仍然不太明白它为什么有效... - Michael Miriti
2
Gradle上的内置代码缩小器可以混淆一些类并删除一些死代码。内置代码缩小器也会删除第三方插件的类。因此,我们不得不添加proguard规则来防止混淆我们的第三方插件类。 - SK. Fuad
你真是让我开心极了 :) 我也遇到了同样的问题,这个解决方法很有效。谢谢! - Felix

6

不要使用热重载/运行,而是停止应用程序并重新启动。


3

在我的情况下,我已经执行了以下步骤来使其工作:

  • 如果尚未创建,请在与MainActivity相同的包中为Android创建Application类。

MyApp.kt

package com.example.flutter_example

import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import com.tekartik.sqflite.SqflitePlugin

class MyApp : FlutterApplication(), PluginRegistrantCallback {

    override fun registerWith(registry: PluginRegistry) {
        com.tekartik.sqflite.SqflitePlugin.registerWith(
                registry.registrarFor("com.tekartik.sqflite.SqflitePlugin"))
    }
}

现在更新你的Android清单文件并提供你的Application类。
<application
        android:name=".MyApp"
  • 现在清理并运行该项目。

3
我会尝试几件事情:
  • 首先确保所有插件都已注册,例如尝试使用SharedPreferences而不是sqflite
  • 如果您的应用程序不是最近创建的,请遵循插件迁移指南:https://flutter.dev/docs/development/packages-and-plugins/plugin-api-migration
  • 尝试在onCreate中删除ImagePickerPlugin的注册(或基本上摆脱MainActivity中的onCreate)。
  • 尝试删除android文件夹并重新创建项目

2

当你在Chrome上运行项目时,程序显示错误是正常的,因为sqflite不支持Chrome。只需在Android / iOS上重新运行该项目,错误将消失。


需要更多的清晰度。 - Tejaswini Dev

1

我在Flutter Windows上遇到了这个错误,按照文档的说明解决了问题。

flutter pub add sqflite_common_ffi

enter image description here

对于Linux/Windows用户,请访问以下链接: https://pub.dev/packages/sqflite_common_ffi

Future<Database>? getDb() {
    _db ??= _initDb();
    return _db;
  }

  // Guaranteed to be called only once.
  Future<Database> _initDb() async {
    Database db;

    if (Platform.isWindows || Platform.isLinux) {
      sqfliteFfiInit();
      var databaseFactory = databaseFactoryFfi;
      db = await databaseFactory.openDatabase(inMemoryDatabasePath);
    } else {
      var databasesPath = await getDatabasesPath();
      final path = '${databasesPath}my_database.db';
      db = await openDatabase(
        path,
        version: 1,
      );
    }
    return db;
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接