Flutter:未处理的异常:MissingPluginException(在通道plugins.flutter.io/shared_preferences上找不到方法getAll的实现)

123

我的Flutter应用程序使用Flutter SharedPreferences插件,并通过platform.invokeMethod将值发送到iOS端。 如果我启动应用程序,我会遇到此错误:

[VERBOSE-2:dart_error.cc(16)] Unhandled exception:
MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences)
#0      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:278:7)
<asynchronous suspension>
#1      SharedPreferences.getInstance (package:shared_preferences/shared_preferences.dart:25:27)
<asynchronous suspension>
#2      main (file:///Users/Developer/workspace/flutter-app/q_flutter2/lib/main.dart:25:53)
<asynchronous suspension>
#3      _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:279:19)
#4      _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:165:12)
如果我注释掉将值发送到iOS端的函数,那么错误就不会显示,并且SharedPreferences可以正常工作。
有人可以帮我吗?

评论不适合进行长时间的讨论;此对话已被移至聊天室 - Martijn Pieters
我将shared_prefs替换为flutter_secure_storage。 - Roman Soviak
我在将应用程序部署到Playstore后面临这个问题(在发布和调试模式下运行/构建都可以正常工作)。有任何想法为什么会发生这种情况吗? - Hugo Sartori
34个回答

114

通道plugins.flutter.io上找不到 getAll 方法的实现。

以上情况发生在您第一次设置插件时,因此必须重新安装。

因此,请卸载并重新安装您的应用程序。


50
我已经卸载和重新安装了,执行了flutter clean命令,但仍然没有起作用。 - Fayaz
4
需要更多细节。 - Llama

60

我进行了大量的研究,找到了答案。在使用共享首选项之前,请将此添加到您的代码中。

SharedPreferences.setMockInitialValues({});

如果在没有数据的情况下使用getAll,会导致程序崩溃。我认为这与iOS无关。即使您使用普通的getString,内部程序也会使用getAll,因此仍然会崩溃。

编辑

我收到了很多关于它在不同会话之间不保留数据的评论。您可以尝试将其放入try和catch语句中进行修复。在try中,调用sharedPreferences.get并捕获错误,然后执行setMockInitialValues。如果sharedPreferences.get没有出现错误,则意味着已经存在数据,无需设置替换旧数据的模拟值。

我不确定它是否有效,如果有人尝试并帮助持久化数据,请告诉我,以便我可以为其他人验证它

编辑2

感谢Edwin Nyawoli,现在我知道为什么它在会话之间没有持续性。虽然我的解决方案是临时的而不是真正的解决方案,但它仍然可能有所帮助。如果有人能帮我在我的新设备上重新创建这个问题,我可以尝试找出一个新的解决方案。请让我知道是否愿意将您的项目上传到github,以便我可以重新创建它。目前,我进行了更多的调查,相信这可能会对您有所帮助:-

在/android/app/build.gradle中

buildTypes {
    release {
        signingConfig signingConfigs.release

        minifyEnabled true
        useProguard true

        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}

改为

buildTypes {
    release {
        signingConfig signingConfigs.release

        minifyEnabled true
        useProguard true

        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}

这个答案不是我写的,它来自于Github问题评论中的这篇评论


4
我们收到了一条警告,提示说setMockInitialValues只应在内部或测试中调用。 - FAjir
使用这行代码我得到了以下错误:Error: Getter not found: 'SharedPreferences'.SharedPreferences.setMockInitialValues({}); - Atul
我建议小心使用这个。对我来说,它在不同的会话之间没有持久化数据。 - blisssan
正如@Konstantin Kozirev所指出的那样,重要的是要注意这不应该在生产应用程序中使用。 - stevenspiel
2
异常已经消失,但是如果应用程序关闭,它会丢失值。重新启动应用程序时会返回 null。 - Vishva Vijay
显示剩余10条评论

38

解决方案

步骤 1:更新 /android/app/build.gradle 中的 buildTypes


android {
    compileSdkVersion 30

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    lintOptions {
        disable 'InvalidPackage'
    }

    defaultConfig {
       ...
    }

    signingConfigs {
        release {
            ...
        }
    }

    buildTypes {
        debug {
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }

        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

            signingConfig signingConfigs.release

            minifyEnabled false
            shrinkResources false

            useProguard true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

步骤二:添加文件android/app/proguard-rules.pro

-keep class androidx.lifecycle.DefaultLifecycleObserver

步骤 3:更新 MainActivity


import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity: FlutterActivity() {
  override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
    GeneratedPluginRegistrant.registerWith(flutterEngine) // add this line
  }
}


5
对我来说,第一步和第二步已经足够了。 - Kedar Sukerkar
1
我还需要在根目录(模块)的main.dart中包含SharedPreferences.setMockInitialValues({});,然后在根目录(模块)的pubspec.yaml中定义shared_preferences,以解决这个问题。我的情况是将Flutter模块包含到本地项目中。 - Huy Tower
1
只需要步骤1。太好了!非常感谢。 - thanhbinh84

37

我之前遇到过这个问题,以下是我解决它的方法:

  1. 运行 flutter clean
  2. 运行 flutter pub get

之后从设备中删除你的调试应用程序。


16

这也让我做了一个噩梦。

  • minifyEnabled false
  • shrinkResources false

    在 app/build.gradle 的 buildTypes 中加入这两行代码,对我来说有效。
android {
    //

    defaultConfig {
        ...
    }

    buildTypes {
        release {
            signingConfig signingConfigs.debug
            minifyEnabled false
            shrinkResources false
        }
    }
}

我以前和shared_prefs一起工作过,但是在最近的项目中遇到了困难。社区应该研究一下这个问题。


13

2022年02月14日,我在后台服务中使用shared_preferences^2.0.8时遇到了问题。在pubspec.yaml中添加以下行解决了该问题:

在 pubspec.yaml 中添加下面这些:

dependency_overrides:
  shared_preferences_android: 2.0.10 

1
谢谢,这解决了我的问题,不知道为什么2.0.11不能用。 - Tx33

13

在将Shared Preferences添加到我的项目并在模拟器上运行后,我遇到了同样的问题。以下步骤解决了我的问题:

  1. 运行'flutter clean'
  2. 运行'flutter pub get'
  3. 从模拟器中删除应用程序

9

对于 Android 部分,您不应该使用

SharedPreferences.setMockInitialValues({});

因为它不能保存您的偏好设置。

相反,将以下行添加到您的app/proguard-rules.pro中:

-keep class androidx.lifecycle.DefaultLifecycleObserver

请看此处了解详情。

相关问题请参见:https://github.com/flutter/flutter/issues/65334


这确实对我有所帮助,但我必须遵循此评论才能使用“proguard-android-optimize.txt” https://github.com/flutter/flutter/issues/65334#issuecomment-760270219 - blisssan
SharedPreferences.setMockInitialValues({}); \n 在 runApp(MyApp()); 上面添加这行代码对我有用。 - Apoorv Pandey

9

遇到了这个问题,并通过完全重新安装应用程序来解决


8

创建一个Flutter虚拟项目来测试这个解决方案在这里,但对我来说没有用。最终我通过更新MainActivity.kt文件来解决问题。

我的解决方案是简单地添加以下一行:flutterEngine.getPlugins().add(SharedPreferencesPlugin())

以下是完整的MainActivity.kt文件:

package com.example.begin.init_begin
import android.content.Context
import android.os.Bundle
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin

类 MainActivity:FlutterActivity(){

override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    flutterEngine.getPlugins().add(SharedPreferencesPlugin())

}

请注意:在我的情况下,GeneratePluginRegistrant.java已经进行了注册,但是像上面展示的添加方式可以解决问题。

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