简体   繁体   中英

"MissingPluginException(No implementation found for method getDatabasesPath on channel com.tekartik.sqflite)" when i use floor database

I'm trying to use floor database but when i want to build database i got below error :

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)

my flutter version:

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

the version of floor,floor_generator and build_runner are as below:

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

in the main.dart i build my database using $FloorAppDatabase:

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

and in the android folder 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());
  }
}

and 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"))

    }

}

I finally found my answer. I must add Sqflite plugin in my MainActivity: SqflitePlugin.registerWith(registrarFor("com.tekartik.sqflite.SqflitePlugin"))

my MainActivity changed as below:

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"))

    }

}

This happen due to the newly added dependencies, where in my case the following command worked. Go to the terminal and then

flutter clean

And re run the project

If you are facing this only on release build then build your release app with proguard rules

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

Create a file on the directory android/app/ name the file as proguard-rules.pro and write inside:

#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

I would try several things:

  • first ensure that all plugins are indeed registered by trying for example to use SharedPreferences instead of sqflite
  • Follow the plugin migration guide: https://flutter.dev/docs/development/packages-and-plugins/plugin-api-migration if your app was not created recently
  • Try to remove the ImagePickerPlugin registration in onCreate (or basically get rid of the onCreate in your MainActivity).
  • Try to delete the android folder and create the project again

In my case, I have done below steps to make it work:

  • Create Application class (if not already created) for android in the same package where you have MainActivity.

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"))
    }
}
  • Now update your Android manifest file and provide your Application class.
<application
        android:name=".MyApp"
  • Now clean and run the project.
flutter clean
flutter run

This worked for me.

Instead of using HotReload / Run, stop the application and start again.

This happended even to me a,just stop the app and rebuild it and it may work as it means that the dependencies are not present.If even that doesn't work,then "flutter clean" will do your job

Silly me, I ran into this error when trying to run my sqflite app in Chrome. Of course sqflite does not support web, so I shouldn't be surprised it's throwing an error. Running in a mobile emulator (or macos) should work.

I got this error on Flutter Windows and solved by following the docs.

flutter pub add sqflite_common_ffi

在此处输入图像描述

Linux/Windows users: 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;
  }

when you run project on chrome, it's normal that the program show an error because sqflite doesn't support on chrome, just re run the project on android/iOs and the error will disappear.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM