因为没有一个既适用于主要操作系统又考虑到多个资源文件分散分布的问题的令人满意的答案,所以我自己编写了一个平台通道解决方案。
在Android(Kotlin)中,我让调用者提供一个"file"参数,因为数据可以分散在多个资源文件中(就像我在问题中描述的那样)。
package my.test
import android.content.*
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterActivity() {
private val CHANNEL = "testChannel"
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
call, result ->
when (call.method) {
"getStringValue" -> {
val key: String? = call.argument<String>("key");
val file: String? = call.argument<String>("file");
when {
key == null -> {
result.error("KEY_MISSING", "Argument 'key' is not provided.", null)
}
file == null -> {
result.error("FILE_MISSING", "Argument 'file' is not provided.", null)
}
else -> {
val value: String? = getStringValue(file, key)
result.success(value)
}
}
}
else -> {
result.notImplemented()
}
}
}
}
private fun getStringValue(file: String, key: String): String? {
return context.getSharedPreferences(
file,
Context.MODE_PRIVATE
).getString(key, null);
}
}
在iOS(Swift)中,由于我正在使用UserDefaults
,因此这不是必需的。
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let platformChannel = FlutterMethodChannel(
name: "testChannel",
binaryMessenger: controller.binaryMessenger
)
platformChannel.setMethodCallHandler({
[weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in
guard call.method == "getStringValue" else {
result(FlutterMethodNotImplemented)
return
}
if let args: Dictionary<String, Any> = call.arguments as? Dictionary<String, Any>,
let number: String = args["key"] as? String, {
self?.getStringValue(key: key, result: result)
return
} else {
result(
FlutterError.init(
code: "KEY_MISSING",
message: "Argument 'key' is not provided.",
details: nil
)
)
}
})
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
private func getStringValue(key: String, result: FlutterResult) -> String? {
let fetchedValue: String? = UserDefaults.object(forKey: key) as? String
result(fetchedValue)
}
我希望
SharedPreferences
包能够增加省略flutter前缀的可能性,使开发者能够轻松地从原生应用程序迁移内容。
我还撰写了一篇博客文章,更详细地解释了问题和解决方案:
https://www.flutterclutter.dev/flutter/tutorials/read-shared-preferences-from-native-apps/2021/9753/。
MethodChannel
。请参见此文章。 - creativecreatorormaybenotPlatformChannel
。 - Michel Feinstein