add checkExist() for Flutter

This commit is contained in:
guoling
2025-04-22 16:39:05 +08:00
parent 61ec001629
commit 85e64c9422
29 changed files with 134 additions and 78 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ org.gradle.jvmargs=-Xmx1536m
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
VERSION_NAME_PREFIX=2.1.0
VERSION_NAME_PREFIX=2.2.0
#VERSION_NAME_SUFFIX=-SNAPSHOT
VERSION_NAME_SUFFIX=
+2 -2
View File
@@ -128,14 +128,14 @@ afterEvaluate {
}
into "$buildDir/intermediates/prefab_package/${variant.name.capitalize()}/prefab/modules/mmkv/libs"
eachFile {
println('hhh before:' + path)
// println('hhh before:' + path)
for (abi in abiFilters) {
if (path.contains("${abi}/")) {
path = path.replace("${abi}/", "android.${abi}/")
break
}
}
println('hhh after:' + path)
// println('hhh after:' + path)
}
// Hook into build process
+1 -1
View File
@@ -98,7 +98,7 @@ repositories {
}
// Define the mmkv version to use
def mmkvVersion = '2.1.0'
def mmkvVersion = '2.2.0'
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
+1 -1
View File
@@ -34,7 +34,7 @@
#include <vector>
#include <unordered_map>
constexpr auto MMKV_VERSION = "v2.1.0";
constexpr auto MMKV_VERSION = "v2.2.0";
#ifdef DEBUG
# define MMKV_DEBUG
+1 -1
View File
@@ -1496,7 +1496,7 @@ static std::pair<MMKVPath_t, MMKVPath_t> getStorage(const std::string &mmapID, c
auto migrateStatus = tryMigrateLegacyMMKVFile(mmapID, relatePath);
if (migrateStatus == MigrateStatus::NoneExist) {
MMKVWarning("file id [%s] not exist in path %s", mmapID.c_str(), relatePath ? relatePath->c_str() : "default");
return false;
return {};
} else if (migrateStatus == MigrateStatus::OldToNewMigrateFail) {
realID = legacyMmapedKVKey(mmapID, relatePath);
} else {
+2 -2
View File
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "MMKV"
s.version = "2.1.0"
s.version = "2.2.0"
s.summary = "MMKV is a cross-platform key-value storage framework developed by WeChat."
s.description = <<-DESC
@@ -33,7 +33,7 @@ Pod::Spec.new do |s|
"CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF" => "NO",
}
s.dependency 'MMKVCore', '~> 2.1.0'
s.dependency 'MMKVCore', '~> 2.2.0'
end
+2 -2
View File
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "MMKVAppExtension"
s.version = "2.1.0"
s.version = "2.2.0"
s.summary = "MMKV is a cross-platform key-value storage framework developed by WeChat."
s.module_name = "MMKVAppExtension"
@@ -31,7 +31,7 @@ Pod::Spec.new do |s|
"GCC_PREPROCESSOR_DEFINITIONS" => "MMKV_IOS_EXTENSION",
}
s.dependency 'MMKVCore', '~> 2.1.0'
s.dependency 'MMKVCore', '~> 2.2.0'
end
+1 -1
View File
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "MMKVCore"
s.version = "2.1.1"
s.version = "2.2.0"
s.summary = "MMKVCore for MMKV. MMKV is a cross-platform key-value storage framework developed by WeChat."
s.description = <<-DESC
+2 -2
View File
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "MMKVWatchExtension"
s.version = "2.1.0"
s.version = "2.2.0"
s.summary = "MMKV is a cross-platform key-value storage framework developed by WeChat."
s.module_name = "MMKVWatchExtension"
@@ -31,7 +31,7 @@ Pod::Spec.new do |s|
"GCC_PREPROCESSOR_DEFINITIONS" => "MMKV_IOS_EXTENSION",
}
s.dependency 'MMKVCore', '~> 2.1.0'
s.dependency 'MMKVCore', '~> 2.2.0'
end
+6 -1
View File
@@ -1,5 +1,10 @@
# MMKV for Flutter Change Log
## v2.1.0 / 2025-03-06
## v2.2.0 / 2025-04-xx
* Add `checkExist()`.
* Reduce file descriptor usage by a half and more.
* Improve multi-process access efficiency by about 20%.
## v2.1.1 / 2025-03-06
This is a **critical hotfix** for v2.1.0. It's highly recommended to upgrade as soon as possible.
* Fix a bug that MMKV instance from non-namespace fails to create.
@@ -24,7 +24,7 @@ if (flutterVersionName == null) {
android {
namespace "com.tencent.mmkv_example"
compileSdkVersion 34
compileSdkVersion 35
lintOptions {
disable 'InvalidPackage'
@@ -33,7 +33,7 @@ android {
defaultConfig {
applicationId "com.tencent.mmkv_example"
minSdkVersion 23
targetSdkVersion 34
targetSdkVersion 35
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
@@ -52,7 +52,7 @@ android {
}
dependencies {
implementation('com.tencent:mmkv:2.1.0')
implementation('com.tencent:mmkv:2.2.0')
constraints {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") {
+2 -2
View File
@@ -38,8 +38,8 @@ target 'Runner' do
# https://blog.cocoapods.org/CocoaPods-1.4.0/
# script_phase :name => 'Fix MMKV Plugin Name', :script => 'sed -i "" "s/@import mmkv;/@import mmkvflutter;/g" ${SRCROOT}/Runner/GeneratedPluginRegistrant.m', :execution_position=>:before_compile
# Specify the dependency from a specific branch
# pod 'MMKVCore', :git => 'https://github.com/Tencent/MMKV.git', :branch => 'dev_namespace'
# pod 'MMKV', :git => 'https://github.com/Tencent/MMKV.git', :branch => 'dev_namespace'
pod 'MMKVCore', :git => 'https://github.com/Tencent/MMKV.git', :branch => 'dev'
pod 'MMKV', :git => 'https://github.com/Tencent/MMKV.git', :branch => 'dev'
end
post_install do |installer|
+35 -31
View File
@@ -26,13 +26,13 @@ import "dart:typed_data";
import "package:flutter/material.dart";
import "package:mmkv/mmkv.dart";
import "package:path_provider_foundation/path_provider_foundation.dart";
import 'package:path_provider/path_provider.dart';
import "package:path_provider/path_provider.dart";
// import "package:posix/posix.dart" show chmod;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
var groupDir = null;
var groupDir;
if (Platform.isIOS) {
final PathProviderFoundation provider = PathProviderFoundation();
groupDir = await provider.getContainerPath(appGroupIdentifier: "group.tencent.mmkv");
@@ -188,33 +188,33 @@ class _MyAppState extends State<MyApp> {
functionalTest();
// testReadOnly();
},
child: Text("Functional Test", style: TextStyle(fontSize: 18))),
child: const Text("Functional Test", style: TextStyle(fontSize: 18))),
TextButton(
onPressed: () {
testReKey();
},
child: Text("Encryption Test", style: TextStyle(fontSize: 18))),
child: const Text("Encryption Test", style: TextStyle(fontSize: 18))),
TextButton(
onPressed: () {
testAutoExpire();
},
child: Text("Auto Expiration Test", style: TextStyle(fontSize: 18))),
child: const Text("Auto Expiration Test", style: TextStyle(fontSize: 18))),
TextButton(
onPressed: () {
testCompareBeforeSet();
},
child: Text("Compare Before Insert/Update Test", style: TextStyle(fontSize: 18))),
child: const Text("Compare Before Insert/Update Test", style: TextStyle(fontSize: 18))),
TextButton(
onPressed: () {
testBackup();
testRestore();
},
child: Text("Backup & Restore Test", style: TextStyle(fontSize: 18))),
child: const Text("Backup & Restore Test", style: TextStyle(fontSize: 18))),
TextButton(
onPressed: () {
testRemoveStorage();
testRemoveStorageAndCheckExist();
},
child: Text("Remove Storage Test", style: TextStyle(fontSize: 18))),
child: const Text("Remove Storage & Check Exist Test", style: TextStyle(fontSize: 18))),
])),
),
);
@@ -260,11 +260,11 @@ class _MyAppState extends State<MyApp> {
print('contains "string": ${mmkv.containsKey('string')}');
str += " with bytes";
var bytes = MMBuffer.fromList(Utf8Encoder().convert(str))!;
var bytes = MMBuffer.fromList(const Utf8Encoder().convert(str))!;
mmkv.encodeBytes("bytes", bytes);
bytes.destroy();
bytes = mmkv.decodeBytes("bytes")!;
print("bytes = ${Utf8Decoder().convert(bytes.asList()!)}");
print("bytes = ${const Utf8Decoder().convert(bytes.asList()!)}");
bytes.destroy();
// test empty bytes
@@ -312,7 +312,7 @@ class _MyAppState extends State<MyApp> {
}
void testReKey() {
final mmapID = "testAES_reKey1";
const mmapID = "testAES_reKey1";
final MMKV kv = testMMKV(mmapID, null, false, null);
kv.reKey("Key_seq_1");
@@ -330,26 +330,26 @@ class _MyAppState extends State<MyApp> {
void testBackup() {
final rootDir = FileSystemEntity.parentOf(MMKV.rootDir);
var backupRootDir = rootDir + "/mmkv_backup_3";
final String mmapID = "test/AES";
final String cryptKey = "Tencent MMKV";
final String otherDir = rootDir + "/mmkv_3";
var backupRootDir = "$rootDir/mmkv_backup_3";
const String mmapID = "test/AES";
const String cryptKey = "Tencent MMKV";
final String otherDir = "$rootDir/mmkv_3";
testMMKV(mmapID, cryptKey, false, otherDir);
final ret = MMKV.backupOneToDirectory(mmapID, backupRootDir, rootDir: otherDir);
print("backup one [$mmapID] return: $ret");
backupRootDir = rootDir + "/mmkv_backup";
backupRootDir = "$rootDir/mmkv_backup";
final count = MMKV.backupAllToDirectory(backupRootDir);
print("backup all count: $count");
}
void testRestore() {
final rootDir = FileSystemEntity.parentOf(MMKV.rootDir);
var backupRootDir = rootDir + "/mmkv_backup_3";
final String mmapID = "test/AES";
final String cryptKey = "Tencent MMKV";
final String otherDir = rootDir + "/mmkv_3";
var backupRootDir = "$rootDir/mmkv_backup_3";
const String mmapID = "test/AES";
const String cryptKey = "Tencent MMKV";
final String otherDir = "$rootDir/mmkv_3";
final kv = MMKV(mmapID, cryptKey: cryptKey, rootDir: otherDir);
kv.encodeString("test_restore", "value before restore");
@@ -360,7 +360,7 @@ class _MyAppState extends State<MyApp> {
print("after restore [${kv.mmapID}] allKeys: ${kv.allKeys}");
}
backupRootDir = rootDir + "/mmkv_backup";
backupRootDir = "$rootDir/mmkv_backup";
final count = MMKV.restoreAllFromDirectory(backupRootDir);
print("restore all count $count");
if (count > 0) {
@@ -390,7 +390,7 @@ class _MyAppState extends State<MyApp> {
}
mmkv.encodeBool("never_expire_key_1", true, MMKV.ExpireNever);
final duration = const Duration(seconds: 2);
const duration = Duration(seconds: 2);
sleep(duration);
print("auto_expire_key_1: ${mmkv.containsKey("auto_expire_key_1")}");
@@ -412,8 +412,8 @@ class _MyAppState extends State<MyApp> {
mmkv.encodeString("key", "extra");
{
final String key = "int";
final int v = 12345;
const String key = "int";
const int v = 12345;
mmkv.encodeInt32(key, v);
final actualSize = mmkv.actualSize;
print("testCompareBeforeSet actualSize = $actualSize");
@@ -431,8 +431,8 @@ class _MyAppState extends State<MyApp> {
}
{
final key = "string";
final v = "w012A🏊🏻good";
const key = "string";
const v = "w012A🏊🏻good";
mmkv.encodeString(key, v);
final actualSize = mmkv.actualSize;
print("testCompareBeforeSet actualSize = $actualSize");
@@ -450,13 +450,15 @@ class _MyAppState extends State<MyApp> {
}
}
void testRemoveStorage() {
void testRemoveStorageAndCheckExist() {
var mmapID = "test_remove";
{
final mmkv = MMKV(mmapID, mode: MMKVMode.MULTI_PROCESS_MODE);
mmkv.encodeBool("bool", true);
}
print("check exist = ${MMKV.checkExist(mmapID)}");
MMKV.removeStorage(mmapID);
print("after remove, check exist = ${MMKV.checkExist(mmapID)}");
{
final mmkv = MMKV(mmapID, mode: MMKVMode.MULTI_PROCESS_MODE);
if (mmkv.count != 0) {
@@ -465,10 +467,12 @@ class _MyAppState extends State<MyApp> {
}
mmapID = "test_remove/sg";
final rootDir = MMKV.rootDir + "_sg";
final rootDir = "${MMKV.rootDir}_sg";
var mmkv = MMKV(mmapID, rootDir: rootDir);
mmkv.encodeBool("bool", true);
print("check exist = ${MMKV.checkExist(mmapID, rootDir: rootDir)}");
MMKV.removeStorage(mmapID, rootDir: rootDir);
print("after remove, check exist = ${MMKV.checkExist(mmapID, rootDir: rootDir)}");
mmkv = MMKV(mmapID, rootDir: rootDir);
if (mmkv.count != 0) {
print("storage not successfully removed");
@@ -476,8 +480,8 @@ class _MyAppState extends State<MyApp> {
}
void testReadOnly() {
final name = "testReadOnly";
final key = "ReadOnly+Key";
const name = "testReadOnly";
const key = "ReadOnly+Key";
{
final mmkv = MMKV(name, cryptKey: key);
_testMMKVImp(mmkv, false);
+15
View File
@@ -757,6 +757,19 @@ class MMKV {
return _int2Bool(ret);
}
/// check the existence of the MMKV
static bool checkExist(String mmapID, {String? rootDir}) {
final mmapIDPtr = mmapID.toNativeUtf8();
final rootDirPtr = _string2Pointer(rootDir);
final ret = _checkExist(mmapIDPtr, rootDirPtr);
calloc.free(mmapIDPtr);
calloc.free(rootDirPtr);
return _int2Bool(ret);
}
void checkContentChangedByOuterProcess() {
}
@@ -958,3 +971,5 @@ final ContentCallbackRegister _registerContentHandler = _mmkvPlatform.registerCo
final void Function(Pointer<Void>) _checkContentChanged = _mmkvPlatform.checkContentChangedFunc();
final bool Function(Pointer<Utf8>) _getNameSpace = _mmkvPlatform.getNameSpaceFunc();
final int Function(Pointer<Utf8> mmapID, Pointer<Utf8> rootPath) _checkExist = _mmkvPlatform.checkExistFunc();
+9 -9
View File
@@ -1,6 +1,6 @@
name: mmkv
description: An efficient, small mobile key-value storage framework developed by WeChat. Works on Android & iOS.
version: 2.1.1
version: 2.2.0
homepage: https://github.com/Tencent/mmkv
repository: https://github.com/Tencent/MMKV/tree/master/flutter/mmkv
@@ -13,17 +13,17 @@ dependencies:
sdk: flutter
ffi: ^2.0.0
mmkv_ios:
'>=2.1.0 <2.2.0'
# path: ../mmkv_ios
# '>=2.2.0 <2.3.0'
path: ../mmkv_ios
mmkv_android:
'>=2.1.0 <2.2.0'
# path: ../mmkv_android
# '>=2.2.0 <2.3.0'
path: ../mmkv_android
mmkv_ohos:
'>=2.1.0 <2.2.0'
# path: ../mmkv_ohos
# '>=2.2.0 <2.3.0'
path: ../mmkv_ohos
mmkv_platform_interface:
'>=2.1.0 <2.2.0'
# path: ../mmkv_platform_interface
# '>=2.2.0 <2.3.0'
path: ../mmkv_platform_interface
dev_dependencies:
test:
+3
View File
@@ -1,4 +1,7 @@
# MMKV Platform Android Change Log
## v2.2.0 / 2025-4-xx
Keep up with native lib v2.2.0.
## v2.1.0 / 2025-02-18
Keep up with native lib v2.1.0.
+4 -4
View File
@@ -8,7 +8,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:8.8.0'
classpath 'com.android.tools.build:gradle:8.9.2'
}
}
@@ -16,7 +16,7 @@ rootProject.allprojects {
repositories {
google()
mavenCentral()
// mavenLocal()
mavenLocal()
}
}
@@ -24,7 +24,7 @@ apply plugin: 'com.android.library'
android {
namespace "com.tencent.mmkvflutter"
compileSdkVersion 34
compileSdkVersion 35
defaultConfig {
minSdkVersion 23
@@ -34,6 +34,6 @@ android {
}
dependencies {
implementation 'com.tencent:mmkv:[2.1.0, 2.2)'
implementation 'com.tencent:mmkv:[2.2.0, 2.3)'
}
}
+3 -3
View File
@@ -1,7 +1,7 @@
name: mmkv_android
description: Android platform implementation of MMKV.
repository: https://github.com/Tencent/MMKV/tree/master/flutter/mmkv_ios
version: 2.1.0
version: 2.2.0
homepage: https://github.com/Tencent/mmkv
environment:
@@ -13,8 +13,8 @@ dependencies:
sdk: flutter
ffi: ^2.0.0
mmkv_platform_interface:
'>=2.1.0 <2.2.0'
# path: ../mmkv_platform_interface
# '>=2.2.0 <2.3.0'
path: ../mmkv_platform_interface
dev_dependencies:
test:
+3
View File
@@ -1,4 +1,7 @@
# MMKV Platform iOS Change Log
## v2.2.0 / 2025-4-xx
Keep up with native lib v2.2.0.
## v2.1.0 / 2025-02-18
Keep up with native lib v2.1.0.
@@ -652,3 +652,15 @@ MMKV_EXPORT bool MMKV_FUNC(getNameSpace)(const char *rootPath) {
}
return false;
}
MMKV_EXPORT bool MMKV_FUNC(checkExist)(const char *mmapID, const char *rootDir) {
auto strID = [NSString stringWithUTF8String:mmapID];
if (rootDir) {
auto root = [NSString stringWithUTF8String:rootDir];
if (root.length > 0) {
return [MMKV checkExist:strID rootPath:root];
}
}
return [MMKV checkExist:strID rootPath:nil];
}
+2 -3
View File
@@ -5,7 +5,7 @@
Pod::Spec.new do |s|
s.name = 'mmkv_ios'
s.version = '2.1.0'
s.version = '2.2.0'
s.summary = 'MMKV is a cross-platform key-value storage framework developed by WeChat.'
s.description = <<-DESC
The MMKV, for Flutter.
@@ -19,7 +19,7 @@ Pod::Spec.new do |s|
s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/MMKVPlugin.h'
s.dependency 'Flutter'
s.dependency 'MMKV', '>= 2.1.0', '< 2.2'
s.dependency 'MMKV', '>= 2.2.0', '< 2.3'
s.platform = :ios, '13.0'
# Flutter.framework does not contain a i386 slice.
@@ -30,4 +30,3 @@ Pod::Spec.new do |s|
}
end
+3 -3
View File
@@ -1,7 +1,7 @@
name: mmkv_ios
description: iOS platform implementation of MMKV.
repository: https://github.com/Tencent/MMKV/tree/master/flutter/mmkv_ios
version: 2.1.0
version: 2.2.0
homepage: https://github.com/Tencent/mmkv
environment:
@@ -13,8 +13,8 @@ dependencies:
sdk: flutter
ffi: ^2.0.0
mmkv_platform_interface:
'>=2.1.0 <2.2.0'
# path: ../mmkv_platform_interface
# '>=2.2.0 <2.3.0'
path: ../mmkv_platform_interface
dev_dependencies:
test:
+3
View File
@@ -1,4 +1,7 @@
# MMKV Platform OHOS Change Log
## v2.2.0 / 2025-4-xx
Keep up with native lib v2.2.0.
## v2.1.0 / 2025-02-18
Keep up with native lib v2.1.0.
+2 -2
View File
@@ -1,13 +1,13 @@
{
"name": "mmkv_ohos",
"version": "1.0.0",
"version": "2.2.0",
"description": "Please describe the basic information.",
"main": "index.ets",
"author": "",
"license": "Apache-2.0",
"dependencies": {
"@ohos/flutter_ohos": "file:./har/flutter.har",
"@tencent/mmkv": ">=2.1.0 <2.2"
"@tencent/mmkv": ">=2.2.0 <2.3"
// "@tencent/mmkv": "file:/Users/lingol/Developer/mmkv/OpenHarmony/MMKV/build/default/outputs/default/MMKV.har"
},
"devDependencies": {},
+3 -3
View File
@@ -1,7 +1,7 @@
name: mmkv_ohos
description: OHOS platform implementation of MMKV.
repository: https://github.com/Tencent/MMKV/tree/master/flutter/mmkv_ohos
version: 2.1.0
version: 2.2.0
homepage: https://github.com/Tencent/mmkv
environment:
@@ -18,8 +18,8 @@ dependencies:
# path: "packages/path_provider/path_provider_ohos"
ffi: ^2.0.0
mmkv_platform_interface:
'>=2.1.0 <2.2.0'
# path: ../mmkv_platform_interface
# '>=2.2.0 <2.3.0'
path: ../mmkv_platform_interface
dev_dependencies:
flutter_test:
@@ -1,4 +1,7 @@
# MMKV Platform Interface Change Log
## v2.2.0 / 2025-4-xx
* Add `checkExist()`.
## v2.1.0 / 2025-02-18
* Bump to 2.1 to setup a breaking change version.
* Add `getNameSpace()`.
@@ -331,4 +331,9 @@ class MMKVPluginPlatformFFI extends MMKVPluginPlatform {
bool Function(Pointer<Utf8> rootPath) getNameSpaceFunc() {
return nativeLib().lookup<NativeFunction<Bool Function(Pointer<Utf8>)>>(nativeFuncName("getNameSpace")).asFunction();
}
@override
int Function(Pointer<Utf8> mmapID, Pointer<Utf8> rootPath) checkExistFunc() {
return nativeLib().lookup<NativeFunction<Int8 Function(Pointer<Utf8>, Pointer<Utf8>)>>(nativeFuncName("checkExist")).asFunction();
}
}
@@ -328,6 +328,10 @@ class MMKVPluginPlatform {
final result = await getTemporaryDirectory();
return result.path;
}
int Function(Pointer<Utf8> mmapID, Pointer<Utf8> rootPath) checkExistFunc() {
throw UnimplementedError();
}
}
typedef LogCallbackWrap = Void Function(Uint32, Pointer<Utf8>, Int32, Pointer<Utf8>, Pointer<Utf8>);
+1 -1
View File
@@ -3,7 +3,7 @@ description: A common platform interface for the MMKV plugin.
repository: https://github.com/Tencent/MMKV/tree/master/flutter/mmkv_platform_interface
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
version: 2.1.0
version: 2.2.0
homepage: https://github.com/Tencent/MMKV
environment: