Giter Club home page Giter Club logo

tencent / mmkv Goto Github PK

View Code? Open in Web Editor NEW
16.9K 283.0 1.9K 45.83 MB

An efficient, small mobile key-value storage framework developed by WeChat. Works on Android, iOS, macOS, Windows, and POSIX.

License: Other

CMake 1.45% Java 15.54% C++ 49.88% C 2.64% Ruby 1.20% Objective-C 4.39% Objective-C++ 11.76% Swift 0.44% Kotlin 0.19% Makefile 0.01% Python 1.22% Assembly 3.05% Dart 5.11% Go 2.80% AIDL 0.02% TypeScript 0.12% Shell 0.11% Batchfile 0.12%
android ios kotlin swift macos key-value wechat flutter golang python

mmkv's Introduction

license PRs Welcome Release Version Platform

中文版本请参看这里

MMKV is an efficient, small, easy-to-use mobile key-value storage framework used in the WeChat application. It's currently available on Android, iOS/macOS, Windows, POSIX and HarmonyOS NEXT.

MMKV for Android

Features

  • Efficient. MMKV uses mmap to keep memory synced with files, and protobuf to encode/decode values, making the most of Android to achieve the best performance.

    • Multi-Process concurrency: MMKV supports concurrent read-read and read-write access between processes.
  • Easy-to-use. You can use MMKV as you go. All changes are saved immediately, no sync, no apply calls needed.

  • Small.

    • A handful of files: MMKV contains process locks, encode/decode helpers and mmap logics, and nothing more. It's really tidy.
    • About 50K in binary size: MMKV adds about 50K per architecture on App size, and much less when zipped (APK).

Getting Started

Installation Via Maven

Add the following lines to build.gradle on your app module:

dependencies {
    implementation 'com.tencent:mmkv:1.3.5'
    // replace "1.3.5" with any available version
}

For other installation options, see Android Setup.

Quick Tutorial

You can use MMKV as you go. All changes are saved immediately, no sync, no apply calls needed.
Setup MMKV on App startup, say your Application class, add these lines:

public void onCreate() {
    super.onCreate();

    String rootDir = MMKV.initialize(this);
    System.out.println("mmkv root: " + rootDir);
    //……
}

MMKV has a global instance, that can be used directly:

import com.tencent.mmkv.MMKV;
    
MMKV kv = MMKV.defaultMMKV();

kv.encode("bool", true);
boolean bValue = kv.decodeBool("bool");

kv.encode("int", Integer.MIN_VALUE);
int iValue = kv.decodeInt("int");

kv.encode("string", "Hello from mmkv");
String str = kv.decodeString("string");

MMKV also supports Multi-Process Access. Full tutorials can be found here Android Tutorial.

Performance

Writing random int for 1000 times, we get this chart:

For more benchmark data, please refer to our benchmark.

MMKV for iOS/macOS

Features

  • Efficient. MMKV uses mmap to keep memory synced with files, and protobuf to encode/decode values, making the most of iOS/macOS to achieve the best performance.

  • Easy-to-use. You can use MMKV as you go, no configurations are needed. All changes are saved immediately, no synchronize calls are needed.

  • Small.

    • A handful of files: MMKV contains encode/decode helpers and mmap logics and nothing more. It's really tidy.
    • Less than 30K in binary size: MMKV adds less than 30K per architecture on App size, and much less when zipped (IPA).

Getting Started

Installation Via CocoaPods:

  1. Install CocoaPods;
  2. Open the terminal, cd to your project directory, run pod repo update to make CocoaPods aware of the latest available MMKV versions;
  3. Edit your Podfile, add pod 'MMKV' to your app target;
  4. Run pod install;
  5. Open the .xcworkspace file generated by CocoaPods;
  6. Add #import <MMKV/MMKV.h> to your source file and we are done.

For other installation options, see iOS/macOS Setup.

Quick Tutorial

You can use MMKV as you go, no configurations are needed. All changes are saved immediately, no synchronize calls are needed. Setup MMKV on App startup, in your -[MyApp application: didFinishLaunchingWithOptions:], add these lines:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // init MMKV in the main thread
    [MMKV initializeMMKV:nil];

    //...
    return YES;
}

MMKV has a global instance, that can be used directly:

MMKV *mmkv = [MMKV defaultMMKV];
    
[mmkv setBool:YES forKey:@"bool"];
BOOL bValue = [mmkv getBoolForKey:@"bool"];
    
[mmkv setInt32:-1024 forKey:@"int32"];
int32_t iValue = [mmkv getInt32ForKey:@"int32"];
    
[mmkv setString:@"hello, mmkv" forKey:@"string"];
NSString *str = [mmkv getStringForKey:@"string"];

MMKV also supports Multi-Process Access. Full tutorials can be found here.

Performance

Writing random int for 10000 times, we get this chart:

For more benchmark data, please refer to our benchmark.

MMKV for Windows

Features

  • Efficient. MMKV uses mmap to keep memory synced with files, and protobuf to encode/decode values, making the most of Windows to achieve the best performance.

    • Multi-Process concurrency: MMKV supports concurrent read-read and read-write access between processes.
  • Easy-to-use. You can use MMKV as you go. All changes are saved immediately, no save, no sync calls are needed.

  • Small.

    • A handful of files: MMKV contains process locks, encode/decode helpers and mmap logics, and nothing more. It's really tidy.
    • About 10K in binary size: MMKV adds about 10K on application size, and much less when zipped.

Getting Started

Installation Via Source

  1. Getting source code from git repository:

    git clone https://github.com/Tencent/MMKV.git
    
  2. Add Core/core.vcxproj to your solution;

  3. Add MMKV project to your project's dependencies;

  4. Add $(OutDir)include to your project's C/C++ -> General -> Additional Include Directories;

  5. Add $(OutDir) to your project's Linker -> General -> Additional Library Directories;

  6. Add mmkv.lib to your project's Linker -> Input -> Additional Dependencies;

  7. Add #include <MMKV/MMKV.h> to your source file and we are done.

note:

  1. MMKV is compiled with MT/MTd runtime by default. If your project uses MD/MDd, you should change MMKV's setting to match your project's (C/C++ -> Code Generation -> Runtime Library), or vice versa.
  2. MMKV is developed with Visual Studio 2017, change the Platform Toolset if you use a different version of Visual Studio.

For other installation options, see Windows Setup.

Quick Tutorial

You can use MMKV as you go. All changes are saved immediately, no sync, no save calls needed.
Setup MMKV on App startup, say in your main(), add these lines:

#include <MMKV/MMKV.h>

int main() {
    std::wstring rootDir = getYourAppDocumentDir();
    MMKV::initializeMMKV(rootDir);
    //...
}

MMKV has a global instance, that can be used directly:

auto mmkv = MMKV::defaultMMKV();

mmkv->set(true, "bool");
std::cout << "bool = " << mmkv->getBool("bool") << std::endl;

mmkv->set(1024, "int32");
std::cout << "int32 = " << mmkv->getInt32("int32") << std::endl;

mmkv->set("Hello, MMKV for Windows", "string");
std::string result;
mmkv->getString("string", result);
std::cout << "string = " << result << std::endl;

MMKV also supports Multi-Process Access. Full tutorials can be found here Windows Tutorial.

MMKV for POSIX

Features

  • Efficient. MMKV uses mmap to keep memory synced with files, and protobuf to encode/decode values, making the most of POSIX to achieve the best performance.

    • Multi-Process concurrency: MMKV supports concurrent read-read and read-write access between processes.
  • Easy-to-use. You can use MMKV as you go. All changes are saved immediately, no save, no sync calls are needed.

  • Small.

    • A handful of files: MMKV contains process locks, encode/decode helpers and mmap logics, and nothing more. It's really tidy.
    • About 7K in binary size: MMKV adds about 7K on application size, and much less when zipped.

Getting Started

Installation Via CMake

  1. Getting source code from the git repository:

    git clone https://github.com/Tencent/MMKV.git
    
  2. Edit your CMakeLists.txt, add those lines:

    add_subdirectory(mmkv/POSIX/src mmkv)
    target_link_libraries(MyApp
        mmkv)
  3. Add #include "MMKV.h" to your source file and we are done.

For other installation options, see POSIX Setup.

Quick Tutorial

You can use MMKV as you go. All changes are saved immediately, no sync, no save calls needed.
Setup MMKV on App startup, say in your main(), add these lines:

#include "MMKV.h"

int main() {
    std::string rootDir = getYourAppDocumentDir();
    MMKV::initializeMMKV(rootDir);
    //...
}

MMKV has a global instance, that can be used directly:

auto mmkv = MMKV::defaultMMKV();

mmkv->set(true, "bool");
std::cout << "bool = " << mmkv->getBool("bool") << std::endl;

mmkv->set(1024, "int32");
std::cout << "int32 = " << mmkv->getInt32("int32") << std::endl;

mmkv->set("Hello, MMKV for Windows", "string");
std::string result;
mmkv->getString("string", result);
std::cout << "string = " << result << std::endl;

MMKV also supports Multi-Process Access. Full tutorials can be found here POSIX Tutorial.

MMKV for HarmonyOS NEXT

Features

  • Efficient. MMKV uses mmap to keep memory synced with file, and protobuf to encode/decode values, making the most of native platform to achieve best performance.

    • Multi-Process concurrency: MMKV supports concurrent read-read and read-write access between processes.
  • Easy-to-use. You can use MMKV as you go. All changes are saved immediately, no sync, no flush calls needed.

  • Small.

    • A handful of files: MMKV contains process locks, encode/decode helpers and mmap logics and nothing more. It's really tidy.
    • About 600K in binary size: MMKV adds about 600K per architecture on App size, and much less when zipped (HAR/HAP).

Getting Started

Installation via OHPM:

ohpm install @tencent/mmkv

Quick Tutorial

You can use MMKV as you go. All changes are saved immediately, no sync, no apply calls needed.
Setup MMKV on App startup, say your EntryAbility.onCreate() function, add these lines:

import { MMKV } from '@tencent/mmkv';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    let appCtx = this.context.getApplicationContext();
    let mmkvRootDir = MMKV.initialize(appCtx);
    console.info('mmkv rootDir: ', mmkvRootDir);
    ……
  }

MMKV has a global instance, that can be used directly:

import { MMKV } from '@tencent/mmkv';
    
let mmkv = MMKV.defaultMMKV();
mmkv.encodeBool('bool', true);
console.info('bool = ', mmkv.decodeBool('bool'));
    
mmkv.encodeInt32('int32', Math.pow(2, 31) - 1);
console.info('max int32 = ', mmkv.decodeInt32('int32'));
    
mmkv.encodeInt64('int', BigInt(2**63) - BigInt(1));
console.info('max int64 = ', mmkv.decodeInt64('int'));
    
let str: string = 'Hello OpenHarmony from MMKV';
mmkv.encodeString('string', str);
console.info('string = ', mmkv.decodeString('string'));

let arrayBuffer: ArrayBuffer = StringToArrayBuffer('Hello OpenHarmony from MMKV with bytes');
mmkv.encodeBytes('bytes', arrayBuffer);
let bytes = mmkv.decodeBytes('bytes');
console.info('bytes = ', ArrayBufferToString(bytes));

As you can see, MMKV is quite easy to use. For the full documentation, see HarmonyOS NEXT Tutorial.

License

MMKV is published under the BSD 3-Clause license. For details check out the LICENSE.TXT.

Change Log

Check out the CHANGELOG.md for details of change history.

Contributing

If you are interested in contributing, check out the CONTRIBUTING.md, also join our Tencent OpenSource Plan.

To give clarity of what is expected of our members, MMKV has adopted the code of conduct defined by the Contributor Covenant, which is widely used. And we think it articulates our values well. For more, check out the Code of Conduct.

FAQ & Feedback

Check out the FAQ first. Should there be any questions, don't hesitate to create issues.

Personal Information Protection Rules

User privacy is taken very seriously: MMKV does not obtain, collect or upload any personal information. Please refer to the MMKV SDK Personal Information Protection Rules for details.

mmkv's People

Contributors

0xflotus avatar 100mango avatar adrielcafe avatar alancheen avatar arcticlampyrid avatar catundercar avatar chenqizheng avatar colmugx avatar cyrilbo avatar damonvvong avatar designerxsh avatar douglowder avatar flyinskyin2013 avatar haoxiqiang avatar j2oe avatar jonyfang avatar kaitian521 avatar lingol avatar maxencehenneron avatar mintunitish avatar mopi1402 avatar mrousavy avatar passerbyloo avatar playhi avatar rookiegan avatar sunnyyoung avatar wangqiang1588 avatar wxxion avatar ysbing avatar zhongwuzw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mmkv's Issues

check crc [mmkv.default] fail, crc32:552857142, m_crcDigest:1502984841

The language of MMKV

e.g. Objective-C, Swift, Java, or Kotlin

Java

The version of MMKV

e.g. v1.0.10

v1.0.11

The platform of MMKV

e.g. iOS or Android

Android

The installation of MMKV

e.g. Cocoapods, Carthage, Maven, AAR Package or Git clone

AAR

What's the issue?

Post the outputs or screenshots for errors.

Explain what you want by example or code in English.

In both the main process and the push process, the push process initialization fails

thread-safe?

The platform of MMKV

Android

What's the issue?

Is this thread-safe?

ActualSize much less than real file size.

The language of MMKV

Java

The version of MMKV

v1.0.10

The platform of MMKV

Android

What's the issue?

OOM caused by mmkv file size too large.
loading [***] with file size 134217728, oldActualSize 6788724, newActualSize 6788839

Only 1000+ key-values occupies 130M.
What's the possible reason for actualSize much less than file size, multi-process read & write in single process mode?

Add demo gif to README

Disclaimer: This is a bot

It looks like your repo is trending. The github_trending_videos Instgram account automatically shows the demo gifs of trending repos in Github.

Your README doesn't seem to have any demo gifs. Add one and the next time the parser runs it will pick it up and post it on its Instagram feed. If you don't want to just close this issue we won't bother you again.

confusedness with encodeString

The language of MMKV

Java

The version of MMKV

v1.0.10

The platform of MMKV

Android

The installation of MMKV

Maven, AAR Package

What's the issue?

call kv.encode("string", null) will not update the value to ""

registerOnSharedPreferenceChangeListener not support

The language of MMKV

e.g. Objective-C, Swift, Java, or Kotlin
java

The version of MMKV

e.g. v1.0.10

v1.0.10

The platform of MMKV

e.g. iOS or Android

Android

The installation of MMKV

e.g. Cocoapods, Carthage, Maven, AAR Package or Git clone

What's the issue?

Post the outputs or screenshots for errors.
registerOnSharedPreferenceChangeListener And unregisterOnSharedPreferenceChangeListener
not suport
Explain what you want by example or code in English.

OnSharedPreferenceChangeListener Is a very common and important API

android studio sync project fail

Error:Parameter specified as non-null is null: method com.android.build.gradle.internal.cxx.configure.JsonGenerationVariantConfiguration., parameter ndkVersion

i hava set
ndk.dir=/Users/xxx/xxx/android-ndk-r10e

Android Studio 3.1
JDK 1.8

Due to NDK version is too low ???? should using NDK r16b?

Stack:
Caused by: java.lang.IllegalArgumentException: Parameter specified as non-null is null: method com.android.build.gradle.internal.cxx.configure.JsonGenerationVariantConfiguration., parameter ndkVersion
at com.android.build.gradle.internal.cxx.configure.JsonGenerationVariantConfiguration.(JsonGenerationVariantConfiguration.kt)
at com.android.build.gradle.tasks.ExternalNativeJsonGenerator.create(ExternalNativeJsonGenerator.java:636)
at com.android.build.gradle.internal.TaskManager.createExternalNativeBuildJsonGenerators(TaskManager.java:1602)
at com.android.build.gradle.internal.LibraryTaskManager.createTasksForVariantScope(LibraryTaskManager.java:178)
at com.android.build.gradle.internal.VariantManager.createTasksForVariantData(VariantManager.java:633)
at com.android.build.gradle.internal.VariantManager.lambda$createAndroidTasks$1(VariantManager.java:381)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.internal.VariantManager.createAndroidTasks(VariantManager.java:377)
at com.android.build.gradle.BasePlugin.lambda$createAndroidTasks$6(BasePlugin.java:800)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.createAndroidTasks(BasePlugin.java:795)
at com.android.build.gradle.BasePlugin.lambda$null$4(BasePlugin.java:690)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:81)
at com.android.build.gradle.BasePlugin.lambda$createTasks$5(BasePlugin.java:686)
at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1$1.run(DefaultListenerBuildOperationDecorator.java:155)
at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.reapply(DefaultUserCodeApplicationContext.java:58)
at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction$1.run(DefaultListenerBuildOperationDecorator.java:152)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
at org.gradle.configuration.internal.DefaultListenerBuildOperationDecorator$BuildOperationEmittingAction.execute(DefaultListenerBuildOperationDecorator.java:149)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:91)
at org.gradle.internal.event.BroadcastDispatch$ActionInvocationHandler.dispatch(BroadcastDispatch.java:80)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:42)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:230)
at org.gradle.internal.event.BroadcastDispatch$SingletonDispatch.dispatch(BroadcastDispatch.java:149)
at org.gradle.internal.event.AbstractBroadcastDispatch.dispatch(AbstractBroadcastDispatch.java:58)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:324)
at org.gradle.internal.event.BroadcastDispatch$CompositeDispatch.dispatch(BroadcastDispatch.java:234)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:140)
at org.gradle.internal.event.ListenerBroadcast.dispatch(ListenerBroadcast.java:37)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy33.afterEvaluate(Unknown Source)
at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:187)
at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate$1.execute(LifecycleProjectEvaluator.java:184)
at org.gradle.api.internal.project.DefaultProject.stepEvaluationListener(DefaultProject.java:1418)
at org.gradle.configuration.project.LifecycleProjectEvaluator$NotifyAfterEvaluate.run(LifecycleProjectEvaluator.java:193)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:110)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:68)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:687)
at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:140)
at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:41)
at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuild.run(DefaultGradleLauncher.java:274)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
at org.gradle.initialization.DefaultGradleLauncher.configureBuild(DefaultGradleLauncher.java:182)
at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:141)
at org.gradle.initialization.DefaultGradleLauncher.getConfiguredBuild(DefaultGradleLauncher.java:119)
at org.gradle.internal.invocation.GradleBuildController$2.call(GradleBuildController.java:86)
at org.gradle.internal.invocation.GradleBuildController$2.call(GradleBuildController.java:83)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:154)
at org.gradle.internal.work.StopShieldingWorkerLeaseService.withLocks(StopShieldingWorkerLeaseService.java:38)
at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:96)
at org.gradle.internal.invocation.GradleBuildController.configure(GradleBuildController.java:83)
at org.gradle.tooling.internal.provider.runner.ClientProvidedBuildActionRunner.run(ClientProvidedBuildActionRunner.java:70)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.run(RunAsBuildOperationBuildActionRunner.java:50)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:300)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:292)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:174)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:90)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:45)
at org.gradle.tooling.internal.provider.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:51)
at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:47)
at org.gradle.launcher.exec.InProcessBuildActionExecuter$1.transform(InProcessBuildActionExecuter.java:44)
at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:79)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:44)
at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:39)
at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:25)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:80)
at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:53)
at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:62)
at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:34)
at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:59)
at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:31)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:59)
at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:44)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:46)
at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:30)
at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
at org.gradle.util.Swapper.swap(Swapper.java:38)
at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:62)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:81)
at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:295)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)

安全 security

可以用MMKV保存一些个人隐私的数据吗? 比如邮箱、密码之类的 (类似KeyChian)

混淆

Android 有混淆规则吗,还是不需要混淆

初始化卡顿然后闪退

        var kv = MMKV.defaultMMKV()

调用这行代码,卡顿,然后就闪退了,除了这个
Fatal signal 11 (SIGSEGV) at 0x00000004 (code=1), thread 17055 (com.zxy.app)
没有看到其他的任何日志。
是我使用方式错了吗。

MMKV.mmkvWithID crash

MMKV.mmkvWithID("test/hello2").encode("hello", "world")

id中使用/会导致崩溃

synchronize is deprecated and will be marked with the NS_DEPRECATED macro in a future release.(from Apple)

This is a great frameworks to solve the key-value read/write problems, and has great performance comparing to NSUserDefaults and SQLite。It use the mmap, protobuf and some elegant strategies。

My question is your idea is base on the NSUserDefaults's poor performance is due to synchronize call, but from apple, synchronize will be deprecated and should be remove the synchronize call. (synchronize is deprecated and will be marked with the NS_DEPRECATED macro in a future release.)

Default value was not returned when decode type and encode type mismatch

If we write some data of type A and read it as type B with the same key, unexpected value will be returned. For example:

MMKV kv = MMKV.mmkvWithID(mmapID, MMKV.SINGLE_PROCESS_MODE, cryptKey);
kv.encode("bool", true);
int val = kv.decodeInt("bool", 100);
System.out.println("decode int with key bool: " + val);

The terminal will print decode int with key bool: 1. That is kind of misleading since we never store any int value with key "bool", meanwhile there was no error or exception thrown when we are doing this implicit casting.

Is this an intentional design?

why not support NSDictionary as NSUserDefault

The language of MMKV

Objective-C

The version of MMKV

v1.0.10

The platform of MMKV

iOS

The installation of MMKV

Cocoapods

What's the issue?

For me, I often use a NSUserDefault to do some simple data persistence. And the NSDictionary is a very important one. Why is there no support for it?

Cannot allocate memory

I always error "fail to mlock crc [mmkv.default]-0x1041b8000, 12:Cannot allocate memory"

Why do you detect self == MMKV.class in initialize ?

+ (void)initialize {
	if (self == MMKV.class) {
		static dispatch_once_t onceToken;
		dispatch_once(&onceToken, ^{
			g_instanceDic = [NSMutableDictionary dictionary];
			g_instanceLock = [[NSRecursiveLock alloc] init];

			MMKVInfo(@"pagesize:%d", DEFAULT_MMAP_SIZE);
		});
	}
}

android project build error, not find Keystore file

The language of MMKV

Java

The version of MMKV

v1.0.10

The platform of MMKV

Android

The installation of MMKV

Git clone

What's the issue?

Post the outputs or screenshots for errors.

> Task :mmkvdemo:validateSigningDebug FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':mmkvdemo:validateSigningDebug'.
> Keystore file '/Users/lingol/AndroidStudioProjects/key1' not found for signing config 'config'.

gradle build error, not find key1

About layout of the mmaped file

After calling mmkv.putInt("int", 100) several times, I got a file named after mmkv id under the app's data folder. By inspecting the file content with xxd, I am a little bit confused about the layout of the file.
image-20181002110606026

  • The first four bytes are value of m_actualSize ,and we have 6700 0000 0x67 = 103 bytes.
  • Then we have 0603 696e 7401 64
    • 06 is the size of the map
    • 03 696e 74 represents the length(03 bytes) and content of the key (696e 74, "int")
    • 01 64 represents the length(01 bytes) and the content of the value (0x64 = 100)

Why do we need to write size of the map into the mmaped file anyway? It seems that the size is of no use when decoding.

unordered_map<string, MMBuffer> MiniPBCoder::decodeOneMap(size_t size) {
unordered_map<string, MMBuffer> dic;
if (size == 0) {
auto length = m_inputData->readInt32();
}
while (!m_inputData->isAtEnd()) {
const auto &key = m_inputData->readString();
if (key.length() > 0) {
auto value = m_inputData->readData();
if (value.length() > 0) {
dic[key] = move(value);
} else {
dic.erase(key);
}
}
}
return dic;
}

some unused variable in aes_core.c

The language of MMKV

Swift

The version of MMKV

v1.0.10

The platform of MMKV

iOS

The installation of MMKV

Cocoapods

What's the issue?

Post the outputs or screenshots for errors.

image

Explain what you want by example or code in English.

What are these things doing?And can we remove these unused variable?

可以设置缓存时间吗

代替SharedPreferences
可以设置缓存时间吗?
比如我缓存时效为1小时,1小时之后拿到的value需要为空或null

进程问题

看了项目描述,初步看了下代码,有以下2点疑问点需要帮助:

  • protobuf文件支持自定义么
  • 跨进程可见么

android minsdk怎么支持下15

The language of MMKV

e.g. Objective-C, Swift, Java, or Kotlin

The version of MMKV

e.g. v1.0.10

The platform of MMKV

e.g. iOS or Android

The installation of MMKV

e.g. Cocoapods, Carthage, Maven, AAR Package or Git clone

What's the issue?

Post the outputs or screenshots for errors.

Explain what you want by example or code in English.

More than one file was found with OS independent path 'lib/x86/libc++_shared.so'

The language of MMKV

e.g. Objective-C, Swift, Java, or Kotlin

Kotlin

The version of MMKV

e.g. v1.0.10

v1.0.10

The platform of MMKV

e.g. iOS or Android

The installation of MMKV

e.g. Cocoapods, Carthage, Maven, AAR Package or Git clone

Maven

What's the issue?

Post the outputs or screenshots for errors.

Explain what you want by example or code in English.
More than one file was found with OS independent path 'lib/x86/libc++_shared.so'

iOS & Objective-C no type detection for Key

The language of MMKV

Objective-C

The version of MMKV

v1.0.10

The platform of MMKV

iOS

The installation of MMKV

Cocoapods

What's the issue?

I found that all set&get methods call 'key.length' for check key vaild, but the passed key will be crash if it is an id type but not a string.

Support for macOS?

[!] The platform of the target TestOfMacOS (macOS 10.13) is not compatible with MMKV (1.0.10), which does not support osx.

如果macOS App是单进程模式,MMKV现在能支持吗?

UnsatisfiedLinkError

The language of MMKV

Java

The version of MMKV

v1.0.10

The platform of MMKV

Android

The installation of MMKV

Maven

What's the issue?

on devices below android 4.4.4

image

关于 API 设计的一些疑惑

- (BOOL)setObject:(id)object forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));

支持的类型只有 NSString/NSData/NSDate 这三种,为什么不是分成三个不同的方法而是采用通用 id 来处理呢?

- (BOOL)setString:(NSString *)string forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));
- (BOOL)setDate:(NSDate *)date forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));
- (BOOL)setData:(NSData *)data forKey:(NSString *)key NS_SWIFT_NAME(set(_:forKey:));

支持object么?

The language of MMKV

e.g. Objective-C, Swift, Java, or Kotlin

支持object么?

The version of MMKV

e.g. v1.0.10

The platform of MMKV

e.g. iOS or Android

The installation of MMKV

e.g. Cocoapods, Carthage, Maven, AAR Package or Git clone

What's the issue?

Post the outputs or screenshots for errors.

Explain what you want by example or code in English.

Flutter

Since Android and iOS are already present, are you considering plugin for cross platforms like Google Flutter ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.