CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-tencent--mmkv-shared

MMKV is an efficient, small, easy-to-use mobile key-value storage framework used in the WeChat application.

Pending
Overview
Eval results
Files

data-management.mddocs/

Data Management and Maintenance

Comprehensive data management including backup/restore operations, file validation, storage cleanup, and performance optimization. MMKV provides extensive tools for maintaining data integrity and optimizing storage usage.

Capabilities

Key Management and Queries

Manage and query keys within MMKV instances.

/**
 * Check whether or not MMKV contains the key.
 * @param key The key of the value
 * @return true if key exists, false otherwise
 */
public boolean containsKey(String key);

/**
 * Get all keys.
 * @return Array of all keys, or null if empty
 */
public String[] allKeys();

/**
 * Get all non-expired keys. Note that this call has costs.
 * @return Array of all non-expired keys, or null if empty
 */
public String[] allNonExpireKeys();

/**
 * Get the total count of all keys.
 * @return The total count of all keys
 */
public long count();

/**
 * Get the total count of all non-expired keys. Note that this call has costs.
 * @return The total count of all non-expired keys
 */
public long countNonExpiredKeys();

Usage Example:

MMKV kv = MMKV.defaultMMKV();

// Add some data
kv.encode("user_name", "Alice");
kv.encode("user_age", 25);
kv.encode("temp_data", "temporary", MMKV.ExpireInMinute);

// Check key existence
if (kv.containsKey("user_name")) {
    String name = kv.decodeString("user_name", "");
    Log.d("MMKV", "User name: " + name);
}

// Get all keys
String[] allKeys = kv.allKeys();
if (allKeys != null) {
    Log.d("MMKV", "Total keys: " + allKeys.length);
    for (String key : allKeys) {
        Log.d("MMKV", "Key: " + key);
    }
}

// Get key counts
long totalCount = kv.count();
long nonExpiredCount = kv.countNonExpiredKeys();
Log.d("MMKV", "Total: " + totalCount + ", Non-expired: " + nonExpiredCount);

// Get only non-expired keys
String[] activeKeys = kv.allNonExpireKeys();
Log.d("MMKV", "Active keys: " + (activeKeys != null ? activeKeys.length : 0));

Value Size Information

Get detailed information about stored values and their memory usage.

/**
 * Get the actual size consumption of the key's value.
 * Note: might be a little bigger than value's length.
 * @param key The key of the value
 * @return Size in bytes of the stored value
 */
public int getValueSize(String key);

/**
 * Get the actual size of the key's value. String's length or byte[]'s length, etc.
 * @param key The key of the value
 * @return Actual size of the value data
 */
public int getValueActualSize(String key);

/**
 * Get the size of the underlying file. Align to the disk block size, typically 4K for an Android device.
 * @return Total file size in bytes
 */
public long totalSize();

/**
 * Get the actual used size of the MMKV instance.
 * This size might increase and decrease as MMKV doing insertion and full write back.
 * @return Actual used size in bytes
 */
public long actualSize();

Usage Example:

// Store various types of data
kv.encode("short_text", "Hello");
kv.encode("long_text", "This is a much longer string that will take more space");
kv.encode("large_data", new byte[10240]); // 10KB byte array

// Analyze storage usage
String[] keys = kv.allKeys();
if (keys != null) {
    for (String key : keys) {
        int storageSize = kv.getValueSize(key);
        int actualSize = kv.getValueActualSize(key);
        Log.d("MMKV", String.format("Key: %s, Storage: %d bytes, Actual: %d bytes", 
            key, storageSize, actualSize));
    }
}

// Get overall file statistics
long totalFileSize = kv.totalSize();
long usedSize = kv.actualSize();
double utilizationRatio = (double) usedSize / totalFileSize;

Log.d("MMKV", String.format("File size: %d KB, Used: %d KB, Utilization: %.1f%%", 
    totalFileSize / 1024, usedSize / 1024, utilizationRatio * 100));

Data Removal Operations

Remove individual keys or clear entire MMKV instances.

/**
 * Remove a single key-value pair.
 * @param key The key to remove
 */
public void removeValueForKey(String key);

/**
 * Batch remove some keys from the MMKV instance.
 * @param arrKeys The keys to be removed
 */
public void removeValuesForKeys(String[] arrKeys);

/**
 * Clear all the key-values inside the MMKV instance.
 * The data file will be trimmed down to pageSize, and some sync operations will be called.
 * If you do not want to trim the file, use clearAllWithKeepingSpace() instead for better performance.
 */
public void clearAll();

/**
 * Faster clearAll() implementation.
 * The file size is kept as previous for later use.
 */
public void clearAllWithKeepingSpace();

Usage Example:

// Remove single key
kv.removeValueForKey("temp_data");

// Remove multiple keys at once
String[] keysToRemove = {"old_cache", "expired_token", "temp_config"};
kv.removeValuesForKeys(keysToRemove);

// Clear all data with file trimming (slower but saves disk space)
kv.clearAll();

// Clear all data keeping file size (faster, good for temporary clearing)
MMKV tempKv = MMKV.mmkvWithID("temp_storage");
tempKv.clearAllWithKeepingSpace(); // Faster for frequent clear operations

// Example: Cleanup old data based on patterns
String[] allKeys = kv.allKeys();
if (allKeys != null) {
    List<String> expiredKeys = new ArrayList<>();
    for (String key : allKeys) {
        if (key.startsWith("cache_") && isExpired(key)) {
            expiredKeys.add(key);
        }
    }
    if (!expiredKeys.isEmpty()) {
        kv.removeValuesForKeys(expiredKeys.toArray(new String[0]));
        Log.d("MMKV", "Removed " + expiredKeys.size() + " expired cache keys");
    }
}

File Management and Optimization

Optimize file usage and perform maintenance operations.

/**
 * The totalSize() of an MMKV instance won't reduce after deleting key-values,
 * call this method after lots of deleting if you care about disk usage.
 * Note that clearAll() has a similar effect.
 */
public void trim();

/**
 * Save all mmap memory to file synchronously.
 * You don't need to call this, really, I mean it.
 * Unless you worry about the device running out of battery.
 */
public void sync();

/**
 * Save all mmap memory to file asynchronously.
 * No need to call this unless you worry about the device running out of battery.
 */
public void async();

/**
 * Clear memory cache of the MMKV instance.
 * You can call it on memory warning.
 * Any subsequent call to the MMKV instance will trigger all key-values loading from the file again.
 */
public void clearMemoryCache();

Usage Example:

// Trim file after bulk deletions
long sizeBefore = kv.totalSize();
// ... perform many deletions ...
kv.trim();
long sizeAfter = kv.totalSize();
Log.d("MMKV", "File size reduced by " + (sizeBefore - sizeAfter) + " bytes");

// Force synchronization before critical operations
kv.sync(); // Synchronous - blocks until complete
// Or use asynchronous version
kv.async(); // Non-blocking

// Handle memory pressure
@Override
public void onTrimMemory(int level) {
    super.onTrimMemory(level);
    switch (level) {
        case TRIM_MEMORY_MODERATE:
        case TRIM_MEMORY_RUNNING_MODERATE:
            // Clear non-critical MMKV caches
            cacheMmkv.clearMemoryCache();
            break;
        case TRIM_MEMORY_COMPLETE:
        case TRIM_MEMORY_RUNNING_CRITICAL:
            // Clear all MMKV memory caches
            kv.clearMemoryCache();
            cacheMmkv.clearMemoryCache();
            break;
    }
}

File Validation and Integrity

Validate MMKV files and check data integrity.

/**
 * Check whether the MMKV file is valid or not.
 * Note: Don't use this to check the existence of the instance, the result is undefined on nonexistent files.
 * @param mmapID The unique ID of the MMKV instance
 * @return true if file is valid, false otherwise
 */
public static boolean isFileValid(String mmapID);

/**
 * Check whether the MMKV file is valid or not on customize folder.
 * @param mmapID The unique ID of the MMKV instance
 * @param rootPath The folder of the MMKV instance, defaults to $(FilesDir)/mmkv
 * @return true if file is valid, false otherwise
 */
public static boolean isFileValid(String mmapID, String rootPath);

/**
 * Check existence of the MMKV file.
 * @param mmapID The unique ID of the MMKV instance
 * @return true if file exists, false otherwise
 */
public static boolean checkExist(String mmapID);

/**
 * Check existence of the MMKV file.
 * @param mmapID The unique ID of the MMKV instance
 * @param rootPath The folder of the MMKV instance, defaults to $(FilesDir)/mmkv
 * @return true if file exists, false otherwise
 */
public static boolean checkExist(String mmapID, String rootPath);

Usage Example:

// Check if MMKV files exist and are valid
String[] instanceIds = {"user_data", "cache_data", "settings"};

for (String instanceId : instanceIds) {
    boolean exists = MMKV.checkExist(instanceId);
    boolean isValid = exists && MMKV.isFileValid(instanceId);
    
    Log.d("MMKV", String.format("Instance %s: exists=%b, valid=%b", 
        instanceId, exists, isValid));
    
    if (exists && !isValid) {
        Log.w("MMKV", "Corrupted MMKV file detected: " + instanceId);
        // Handle corruption - maybe restore from backup or recreate
        handleCorruptedFile(instanceId);
    }
}

private void handleCorruptedFile(String instanceId) {
    // Remove corrupted file
    boolean removed = MMKV.removeStorage(instanceId);
    if (removed) {
        Log.d("MMKV", "Removed corrupted file: " + instanceId);
        // Recreate with default values
        MMKV newInstance = MMKV.mmkvWithID(instanceId);
        initializeDefaultValues(newInstance);
    }
}

Storage Removal

Permanently remove MMKV storage files.

/**
 * Remove the storage of the MMKV, including the data file & meta file (.crc).
 * Note: the existing instance (if any) will be closed & destroyed.
 * @param mmapID The unique ID of the MMKV instance
 * @return true if removal was successful, false otherwise
 */
public static boolean removeStorage(String mmapID);

/**
 * Remove the storage of the MMKV, including the data file & meta file (.crc).
 * Note: the existing instance (if any) will be closed & destroyed.
 * @param mmapID The unique ID of the MMKV instance
 * @param rootPath The folder of the MMKV instance, defaults to $(FilesDir)/mmkv
 * @return true if removal was successful, false otherwise
 */
public static boolean removeStorage(String mmapID, String rootPath);

Usage Example:

// Clean up temporary storage
boolean tempRemoved = MMKV.removeStorage("temp_cache");
if (tempRemoved) {
    Log.d("MMKV", "Temporary cache storage removed");
}

// Remove storage with custom path
File customDir = new File(getExternalFilesDir(null), "custom_mmkv");
boolean customRemoved = MMKV.removeStorage("custom_data", customDir.getAbsolutePath());

// Bulk cleanup of old instances
String[] oldInstances = {"old_cache_v1", "deprecated_settings", "temp_data_2023"};
int removedCount = 0;
for (String instanceId : oldInstances) {
    if (MMKV.removeStorage(instanceId)) {
        removedCount++;
    }
}
Log.d("MMKV", "Removed " + removedCount + " old storage instances");

Backup and Restore Operations

Comprehensive backup and restore functionality for data protection and migration.

/**
 * Backup one MMKV instance to dstDir.
 * @param mmapID The MMKV ID to backup
 * @param dstDir The backup destination directory
 * @param rootPath The customize root path of the MMKV, if null then backup from the root dir of MMKV
 * @return true if backup was successful, false otherwise
 */
public static boolean backupOneToDirectory(String mmapID, String dstDir, String rootPath);

/**
 * Restore one MMKV instance from srcDir.
 * @param mmapID The MMKV ID to restore
 * @param srcDir The restore source directory
 * @param rootPath The customize root path of the MMKV, if null then restore to the root dir of MMKV
 * @return true if restore was successful, false otherwise
 */
public static boolean restoreOneMMKVFromDirectory(String mmapID, String srcDir, String rootPath);

/**
 * Backup all MMKV instances from default root dir to dstDir.
 * @param dstDir The backup destination directory
 * @return Count of MMKV instances successfully backed up
 */
public static long backupAllToDirectory(String dstDir);

/**
 * Restore all MMKV instances from srcDir to default root dir.
 * @param srcDir The restore source directory
 * @return Count of MMKV instances successfully restored
 */
public static long restoreAllFromDirectory(String srcDir);

Usage Example:

// Backup individual instance
File backupDir = new File(getExternalFilesDir(null), "mmkv_backup");
if (!backupDir.exists()) {
    backupDir.mkdirs();
}

boolean backupSuccess = MMKV.backupOneToDirectory(
    "user_data", 
    backupDir.getAbsolutePath(), 
    null
);

if (backupSuccess) {
    Log.d("MMKV", "User data backed up successfully");
} else {
    Log.e("MMKV", "Failed to backup user data");
}

// Restore individual instance
File restoreDir = new File(getExternalFilesDir(null), "mmkv_backup");
boolean restoreSuccess = MMKV.restoreOneMMKVFromDirectory(
    "user_data",
    restoreDir.getAbsolutePath(),
    null
);

// Backup all instances
long backedUpCount = MMKV.backupAllToDirectory(backupDir.getAbsolutePath());
Log.d("MMKV", "Backed up " + backedUpCount + " MMKV instances");

// Restore all instances
long restoredCount = MMKV.restoreAllFromDirectory(restoreDir.getAbsolutePath());
Log.d("MMKV", "Restored " + restoredCount + " MMKV instances");

// Automated backup strategy
private void performRegularBackup() {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US);
    String timestamp = sdf.format(new Date());
    
    File backupDir = new File(getExternalFilesDir(null), "mmkv_backup_" + timestamp);
    backupDir.mkdirs();
    
    long backupCount = MMKV.backupAllToDirectory(backupDir.getAbsolutePath());
    
    if (backupCount > 0) {
        Log.d("MMKV", "Backup completed: " + backupCount + " instances");
        // Keep only last 5 backups
        cleanupOldBackups();
    }
}

Data Import Operations

Import data from other MMKV instances or SharedPreferences.

/**
 * Import all key-value items from src MMKV instance.
 * @param src Source MMKV instance to import from
 * @return Count of items imported
 */
public long importFrom(MMKV src);

/**
 * Atomically migrate all key-values from an existent SharedPreferences to the MMKV instance.
 * @param preferences The SharedPreferences to import from
 * @return The total count of key-values imported
 */
public int importFromSharedPreferences(SharedPreferences preferences);

Usage Example:

// Migrate from SharedPreferences to MMKV
SharedPreferences oldPrefs = getSharedPreferences("old_settings", MODE_PRIVATE);
MMKV newKv = MMKV.mmkvWithID("migrated_settings");

int migratedCount = newKv.importFromSharedPreferences(oldPrefs);
Log.d("MMKV", "Migrated " + migratedCount + " settings from SharedPreferences");

// Merge data from multiple MMKV instances
MMKV masterKv = MMKV.mmkvWithID("master_data");
MMKV tempKv1 = MMKV.mmkvWithID("temp_data_1");
MMKV tempKv2 = MMKV.mmkvWithID("temp_data_2");

long imported1 = masterKv.importFrom(tempKv1);
long imported2 = masterKv.importFrom(tempKv2);

Log.d("MMKV", "Imported " + (imported1 + imported2) + " items to master instance");

// Clean up temporary instances after import
MMKV.removeStorage("temp_data_1");
MMKV.removeStorage("temp_data_2");

Instance Lifecycle Management

Properly manage MMKV instance lifecycle and resources.

/**
 * Call this method if the MMKV instance is no longer needed in the near future.
 * Any subsequent call to any MMKV instances with the same ID is undefined behavior.
 */
public void close();

Usage Example:

public class DataManager {
    private MMKV cacheKv;
    private MMKV userKv;
    
    public void initialize() {
        cacheKv = MMKV.mmkvWithID("app_cache");
        userKv = MMKV.mmkvWithID("user_data");
    }
    
    public void cleanup() {
        // Close instances when no longer needed
        if (cacheKv != null) {
            cacheKv.close();
            cacheKv = null;
        }
        
        if (userKv != null) {
            userKv.close();
            userKv = null;
        }
    }
    
    // Call during app lifecycle events
    @Override
    protected void onDestroy() {
        super.onDestroy();
        cleanup();
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-com-tencent--mmkv-shared

docs

advanced-features.md

data-management.md

encryption.md

index.md

initialization.md

instance-management.md

multi-process.md

storage-operations.md

tile.json