or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mddata-operations.mdindex.mdinitialization.mdinstance-management.mdnamespace.mdprocess-management.mdshared-preferences.mdutility-types.md

process-management.mddocs/

0

# Process Management and Synchronization

1

2

MMKV provides robust multi-process synchronization capabilities, allowing safe concurrent access across Android processes with file locking, content change notifications, and automatic synchronization.

3

4

## Capabilities

5

6

### Process Locking

7

8

MMKV provides inter-process exclusive locking for safe concurrent access across multiple processes.

9

10

```java { .api }

11

/**

12

* Exclusively inter-process lock the MMKV instance.

13

* It will block and wait until it successfully locks the file.

14

* It will make no effect if the MMKV instance is created with SINGLE_PROCESS_MODE.

15

*/

16

void lock();

17

18

/**

19

* Exclusively inter-process unlock the MMKV instance.

20

* It will make no effect if the MMKV instance is created with SINGLE_PROCESS_MODE.

21

*/

22

void unlock();

23

24

/**

25

* Try exclusively inter-process lock the MMKV instance.

26

* It will not block if the file has already been locked by another process.

27

* It will make no effect if the MMKV instance is created with SINGLE_PROCESS_MODE.

28

* @return True if successfully locked, otherwise return immediately with False

29

*/

30

boolean tryLock();

31

```

32

33

**Usage Examples:**

34

35

```java

36

// Create multi-process MMKV instance

37

MMKV sharedKv = MMKV.mmkvWithID("shared_data", MMKV.MULTI_PROCESS_MODE);

38

39

// Blocking lock - waits until lock is acquired

40

sharedKv.lock();

41

try {

42

// Critical section - only one process can access at a time

43

sharedKv.encode("shared_counter", sharedKv.decodeInt("shared_counter", 0) + 1);

44

sharedKv.encode("last_modified", System.currentTimeMillis());

45

} finally {

46

// Always unlock in finally block

47

sharedKv.unlock();

48

}

49

50

// Non-blocking lock attempt

51

if (sharedKv.tryLock()) {

52

try {

53

// Got the lock, perform operations

54

sharedKv.encode("optional_update", "updated");

55

} finally {

56

sharedKv.unlock();

57

}

58

} else {

59

Log.d("MMKV", "Could not acquire lock, skipping update");

60

}

61

```

62

63

### Data Synchronization

64

65

MMKV provides explicit synchronization methods for ensuring data persistence, though data is normally persisted immediately.

66

67

```java { .api }

68

/**

69

* Save all mmap memory to file synchronously.

70

* You don't need to call this, really, I mean it.

71

* Unless you worry about the device running out of battery.

72

*/

73

void sync();

74

75

/**

76

* Save all mmap memory to file asynchronously.

77

* No need to call this unless you worry about the device running out of battery.

78

*/

79

void async();

80

```

81

82

**Usage Examples:**

83

84

```java

85

MMKV kv = MMKV.mmkvWithID("important_data");

86

87

// Store critical data

88

kv.encode("critical_setting", importantValue);

89

90

// Force synchronous write to disk (usually not needed)

91

kv.sync();

92

93

// Or force asynchronous write

94

kv.async();

95

96

// Note: MMKV automatically persists data immediately, these calls are optional

97

```

98

99

### Content Change Notifications

100

101

MMKV provides inter-process content change notifications to detect when data is modified by other processes.

102

103

```java { .api }

104

/**

105

* Register for MMKV inter-process content change notification.

106

* The notification will trigger only when any method is manually called on the MMKV instance.

107

* For example checkContentChangedByOuterProcess().

108

* @param notify The notification handler

109

*/

110

static void registerContentChangeNotify(MMKVContentChangeNotification notify);

111

112

/**

113

* Unregister for MMKV inter-process content change notification.

114

*/

115

static void unregisterContentChangeNotify();

116

117

/**

118

* Check inter-process content change manually.

119

*/

120

void checkContentChangedByOuterProcess();

121

```

122

123

**Usage Examples:**

124

125

```java

126

// Set up content change notification

127

MMKV.registerContentChangeNotify(new MMKVContentChangeNotification() {

128

@Override

129

public void onContentChangedByOuterProcess(String mmapID) {

130

Log.d("MMKV", "Content changed in instance: " + mmapID);

131

132

// Refresh UI or reload data as needed

133

if ("shared_config".equals(mmapID)) {

134

reloadConfiguration();

135

}

136

}

137

});

138

139

// In your activity or service

140

MMKV sharedConfig = MMKV.mmkvWithID("shared_config", MMKV.MULTI_PROCESS_MODE);

141

142

// Periodically check for changes from other processes

143

private void checkForUpdates() {

144

sharedConfig.checkContentChangedByOuterProcess();

145

// If content changed, onContentChangedByOuterProcess() will be called

146

}

147

148

// Clean up when done

149

@Override

150

protected void onDestroy() {

151

super.onDestroy();

152

MMKV.unregisterContentChangeNotify();

153

}

154

```

155

156

### Process Mode Management

157

158

MMKV provides utilities for managing and validating process modes to prevent conflicts.

159

160

```java { .api }

161

/**

162

* Manually enable the process mode checker.

163

* By default, it's automatically enabled in DEBUG build, and disabled in RELEASE build.

164

* If it's enabled, MMKV will throw exceptions when an MMKV instance is created with mismatch process mode.

165

*/

166

static void enableProcessModeChecker();

167

168

/**

169

* Manually disable the process mode checker.

170

* By default, it's automatically enabled in DEBUG build, and disabled in RELEASE build.

171

* If it's enabled, MMKV will throw exceptions when an MMKV instance is created with mismatch process mode.

172

*/

173

static void disableProcessModeChecker();

174

175

/**

176

* Check if this instance is in multi-process mode.

177

* @return True if in multi-process mode, False otherwise

178

*/

179

boolean isMultiProcess();

180

181

/**

182

* Check if this instance is in read-only mode.

183

* @return True if in read-only mode, False otherwise

184

*/

185

boolean isReadOnly();

186

```

187

188

**Usage Examples:**

189

190

```java

191

// Enable strict process mode checking for debugging

192

MMKV.enableProcessModeChecker();

193

194

// Create instances

195

MMKV singleKv = MMKV.mmkvWithID("single_data", MMKV.SINGLE_PROCESS_MODE);

196

MMKV multiKv = MMKV.mmkvWithID("multi_data", MMKV.MULTI_PROCESS_MODE);

197

198

// Verify process modes

199

Log.d("MMKV", "Single KV multi-process: " + singleKv.isMultiProcess()); // false

200

Log.d("MMKV", "Multi KV multi-process: " + multiKv.isMultiProcess()); // true

201

202

// This would throw an exception if process mode checker is enabled

203

// and "multi_data" was previously opened with SINGLE_PROCESS_MODE

204

try {

205

MMKV conflictKv = MMKV.mmkvWithID("multi_data", MMKV.SINGLE_PROCESS_MODE);

206

} catch (IllegalArgumentException e) {

207

Log.e("MMKV", "Process mode conflict: " + e.getMessage());

208

}

209

210

// Disable checking for production

211

MMKV.disableProcessModeChecker();

212

```

213

214

### Anonymous Shared Memory for Inter-Process Communication

215

216

MMKV supports Anonymous Shared Memory (ashmem) for high-performance inter-process data sharing without disk persistence.

217

218

```java { .api }

219

/**

220

* Create an MMKV instance base on Anonymous Shared Memory, aka not synced to any disk files.

221

* @param context The context of Android App, usually from Application

222

* @param mmapID The unique ID of the MMKV instance

223

* @param size The maximum size of the underlying Anonymous Shared Memory.

224

* Anonymous Shared Memory on Android can't grow dynamically, must set an appropriate size on creation

225

* @param mode The process mode of the MMKV instance, defaults to SINGLE_PROCESS_MODE

226

* @param cryptKey The encryption key of the MMKV instance (no more than 16 bytes)

227

* @throws RuntimeException if there's a runtime error

228

*/

229

static MMKV mmkvWithAshmemID(Context context, String mmapID, int size, int mode, String cryptKey);

230

231

/**

232

* @return The file descriptor of the ashmem of the MMKV file

233

*/

234

int ashmemFD();

235

236

/**

237

* @return The file descriptor of the ashmem of the MMKV crc file

238

*/

239

int ashmemMetaFD();

240

```

241

242

**Usage Examples:**

243

244

```java

245

// Create ashmem instance for inter-process communication

246

MMKV ashmemKv = MMKV.mmkvWithAshmemID(

247

this,

248

"ipc_data",

249

1024 * 1024, // 1MB max size

250

MMKV.MULTI_PROCESS_MODE,

251

null // No encryption

252

);

253

254

// Use like regular MMKV instance

255

ashmemKv.encode("shared_message", "Hello from process A");

256

ashmemKv.encode("shared_timestamp", System.currentTimeMillis());

257

258

// Get file descriptors for passing to other processes

259

int dataFD = ashmemKv.ashmemFD();

260

int metaFD = ashmemKv.ashmemMetaFD();

261

262

// Pass these FDs to other processes via Binder/AIDL

263

// The receiving process can create MMKV instance from FDs

264

```

265

266

### Multi-Process Best Practices

267

268

Guidelines and patterns for effective multi-process MMKV usage.

269

270

```java

271

// Example multi-process architecture

272

public class SharedDataManager {

273

private static final String SHARED_INSTANCE_ID = "app_shared_data";

274

private final MMKV sharedKv;

275

276

public SharedDataManager(Context context) {

277

// Always use MULTI_PROCESS_MODE for shared data

278

sharedKv = MMKV.mmkvWithID(SHARED_INSTANCE_ID, MMKV.MULTI_PROCESS_MODE);

279

280

// Set up change notifications

281

MMKV.registerContentChangeNotify(this::onContentChanged);

282

}

283

284

public void updateSharedConfig(String key, Object value) {

285

sharedKv.lock();

286

try {

287

// Update with timestamp for conflict resolution

288

sharedKv.encode(key + "_timestamp", System.currentTimeMillis());

289

290

if (value instanceof String) {

291

sharedKv.encode(key, (String) value);

292

} else if (value instanceof Integer) {

293

sharedKv.encode(key, (Integer) value);

294

}

295

// Handle other types...

296

297

} finally {

298

sharedKv.unlock();

299

}

300

}

301

302

public <T> T getSharedConfig(String key, Class<T> type, T defaultValue) {

303

// Check for updates from other processes

304

sharedKv.checkContentChangedByOuterProcess();

305

306

if (type == String.class) {

307

return (T) sharedKv.decodeString(key, (String) defaultValue);

308

} else if (type == Integer.class) {

309

return (T) Integer.valueOf(sharedKv.decodeInt(key, (Integer) defaultValue));

310

}

311

// Handle other types...

312

313

return defaultValue;

314

}

315

316

private void onContentChanged(String mmapID) {

317

if (SHARED_INSTANCE_ID.equals(mmapID)) {

318

// Notify UI components about data changes

319

LocalBroadcastManager.getInstance(context)

320

.sendBroadcast(new Intent("SHARED_DATA_CHANGED"));

321

}

322

}

323

}

324

```

325

326

## Types

327

328

```java { .api }

329

/**

330

* Inter-process content change notification.

331

* Triggered by any method call, such as getXXX() or setXXX() or checkContentChangedByOuterProcess().

332

*/

333

interface MMKVContentChangeNotification {

334

/**

335

* Inter-process content change notification.

336

* Triggered by any method call, such as getXXX() or setXXX() or checkContentChangedByOuterProcess().

337

* @param mmapID The unique ID of the changed MMKV instance

338

*/

339

void onContentChangedByOuterProcess(String mmapID);

340

}

341

342

/**

343

* A helper class for MMKV based on Anonymous Shared Memory.

344

*/

345

class ParcelableMMKV implements Parcelable {

346

/**

347

* Create from existing MMKV instance

348

* @param mmkv The MMKV instance to wrap

349

*/

350

ParcelableMMKV(MMKV mmkv);

351

352

/**

353

* Convert back to MMKV instance

354

* @return MMKV instance, or null if invalid

355

*/

356

MMKV toMMKV();

357

358

// Parcelable implementation for passing between processes

359

int describeContents();

360

void writeToParcel(Parcel dest, int flags);

361

static final Parcelable.Creator<ParcelableMMKV> CREATOR;

362

}

363

364

/**

365

* A helper class for getting process information

366

*/

367

class MMKVContentProvider extends ContentProvider {

368

/**

369

* Get process name by process ID

370

* @param context Application context

371

* @param pid Process ID

372

* @return Process name or empty string if not found

373

*/

374

static String getProcessNameByPID(Context context, int pid);

375

376

/**

377

* Get content provider URI for ashmem operations

378

* @param context Application context

379

* @return Content provider URI, or null if not configured

380

*/

381

static Uri contentUri(Context context);

382

}

383

```

384

385

## Process Mode Constants

386

387

```java { .api }

388

/**

389

* Single-process mode. The default mode on an MMKV instance.

390

*/

391

static final int SINGLE_PROCESS_MODE = 1;

392

393

/**

394

* Multi-process mode.

395

* To enable multi-process accessing of an MMKV instance, you must set this mode whenever you getting that instance.

396

*/

397

static final int MULTI_PROCESS_MODE = 2;

398

399

/**

400

* Read-only mode.

401

*/

402

static final int READ_ONLY_MODE = 32;

403

```

404

405

## Performance Considerations

406

407

- **Single-process mode**: Fastest performance, no locking overhead

408

- **Multi-process mode**: Slight performance overhead due to file locking

409

- **Ashmem mode**: Best for temporary data sharing between processes

410

- **Content change notifications**: Minimal overhead, triggered only on manual checks

411

- **Process mode checker**: Should be disabled in production builds for optimal performance