or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mddata-management.mdencryption.mdindex.mdinitialization.mdinstance-management.mdmulti-process.mdstorage-operations.md

multi-process.mddocs/

0

# Multi-Process Support

1

2

Advanced multi-process functionality for safe concurrent access across Android processes. MMKV provides robust inter-process synchronization, locking mechanisms, and content change notifications for multi-process Android applications.

3

4

## Capabilities

5

6

### Inter-Process Locking

7

8

Exclusive locking mechanisms to ensure 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

public 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

public 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

public boolean tryLock();

31

```

32

33

**Usage Example:**

34

35

```java

36

// Create multi-process MMKV instance

37

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

38

39

// Critical section with blocking lock

40

multiProcessKv.lock();

41

try {

42

// Perform atomic operations

43

int counter = multiProcessKv.decodeInt("global_counter", 0);

44

counter++;

45

multiProcessKv.encode("global_counter", counter);

46

multiProcessKv.encode("last_updated", System.currentTimeMillis());

47

} finally {

48

multiProcessKv.unlock();

49

}

50

51

// Non-blocking lock attempt

52

if (multiProcessKv.tryLock()) {

53

try {

54

// Quick operation that shouldn't wait

55

multiProcessKv.encode("process_status", "active");

56

} finally {

57

multiProcessKv.unlock();

58

}

59

} else {

60

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

61

}

62

```

63

64

### Content Change Detection

65

66

Monitor changes made by other processes to shared MMKV instances.

67

68

```java { .api }

69

/**

70

* Check inter-process content change manually.

71

*/

72

public void checkContentChangedByOuterProcess();

73

74

/**

75

* Register for MMKV inter-process content change notification.

76

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

77

* @param notify The notification handler

78

*/

79

public static void registerContentChangeNotify(MMKVContentChangeNotification notify);

80

81

/**

82

* Unregister for MMKV inter-process content change notification.

83

*/

84

public static void unregisterContentChangeNotify();

85

```

86

87

**Usage Example:**

88

89

```java

90

// Register global content change notification

91

MMKV.registerContentChangeNotify(new MMKVContentChangeNotification() {

92

@Override

93

public void onContentChangedByOuterProcess(String mmapID) {

94

Log.d("MMKV", "Content changed by another process: " + mmapID);

95

// Refresh UI or reload data

96

refreshDataFromMMKV(mmapID);

97

}

98

});

99

100

// Check for changes manually

101

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

102

sharedKv.checkContentChangedByOuterProcess(); // Triggers notification if changed

103

104

// Unregister when no longer needed

105

@Override

106

protected void onDestroy() {

107

super.onDestroy();

108

MMKV.unregisterContentChangeNotify();

109

}

110

```

111

112

### Process Mode Validation

113

114

Validate and manage process mode settings for debugging multi-process access patterns.

115

116

```java { .api }

117

/**

118

* Manually enable the process mode checker.

119

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

120

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

121

*/

122

public static void enableProcessModeChecker();

123

124

/**

125

* Manually disable the process mode checker.

126

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

127

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

128

*/

129

public static void disableProcessModeChecker();

130

131

/**

132

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

133

* @return true if multi-process mode, false otherwise

134

*/

135

public boolean isMultiProcess();

136

```

137

138

**Usage Example:**

139

140

```java

141

// Enable process mode checking for debugging

142

if (BuildConfig.DEBUG) {

143

MMKV.enableProcessModeChecker();

144

}

145

146

// Create instances with proper mode

147

MMKV singleProcessKv = MMKV.mmkvWithID("local_data", MMKV.SINGLE_PROCESS_MODE);

148

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

149

150

// Verify process mode

151

if (multiProcessKv.isMultiProcess()) {

152

Log.d("MMKV", "Instance supports multi-process access");

153

} else {

154

Log.w("MMKV", "Instance is single-process only");

155

}

156

157

// Disable checking in production

158

if (!BuildConfig.DEBUG) {

159

MMKV.disableProcessModeChecker();

160

}

161

```

162

163

### Anonymous Shared Memory for Inter-Process Communication

164

165

Use Anonymous Shared Memory (ashmem) for temporary inter-process data sharing without persistent storage.

166

167

```java { .api }

168

/**

169

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

170

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

171

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

172

* @param mmapID The unique ID of the MMKV instance

173

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

174

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

175

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

176

* @return MMKV instance

177

* @throws RuntimeException if there's a runtime error

178

*/

179

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

180

181

/**

182

* Get an ashmem MMKV instance that has been initiated by another process.

183

* @param mmapID The unique ID of the MMKV instance

184

* @param fd The file descriptor of the ashmem of the MMKV file

185

* @param metaFD The file descriptor of the ashmem of the MMKV crc file

186

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

187

* @return MMKV instance

188

* @throws RuntimeException if there's a runtime error

189

*/

190

public static MMKV mmkvWithAshmemFD(String mmapID, int fd, int metaFD, String cryptKey);

191

192

/**

193

* Get the file descriptor of the ashmem of the MMKV file.

194

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

195

*/

196

public int ashmemFD();

197

198

/**

199

* Get the file descriptor of the ashmem of the MMKV crc file.

200

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

201

*/

202

public int ashmemMetaFD();

203

```

204

205

**Usage Example:**

206

207

```java

208

// Create ashmem instance for inter-process communication

209

MMKV ashmemKv = MMKV.mmkvWithAshmemID(

210

this,

211

"ipc_channel",

212

1024 * 1024, // 1MB maximum size

213

MMKV.MULTI_PROCESS_MODE,

214

null

215

);

216

217

// Use for temporary data sharing

218

ashmemKv.encode("current_state", "processing");

219

ashmemKv.encode("progress", 45);

220

ashmemKv.encode("result_data", resultBytes);

221

222

// Get file descriptors for passing to other processes

223

int dataFD = ashmemKv.ashmemFD();

224

int metaFD = ashmemKv.ashmemMetaFD();

225

226

// In another process, recreate from file descriptors

227

MMKV receivedKv = MMKV.mmkvWithAshmemFD("ipc_channel", dataFD, metaFD, null);

228

String state = receivedKv.decodeString("current_state", "unknown");

229

int progress = receivedKv.decodeInt("progress", 0);

230

```

231

232

### Multi-Process Data Import

233

234

Import data between MMKV instances across process boundaries.

235

236

```java { .api }

237

/**

238

* Import all key-value items from src MMKV instance.

239

* @param src Source MMKV instance to import from

240

* @return Count of items imported

241

*/

242

public long importFrom(MMKV src);

243

244

/**

245

* Atomically migrate all key-values from an existent SharedPreferences to the MMKV instance.

246

* @param preferences The SharedPreferences to import from

247

* @return The total count of key-values imported

248

*/

249

public int importFromSharedPreferences(SharedPreferences preferences);

250

```

251

252

**Usage Example:**

253

254

```java

255

// Import from another MMKV instance

256

MMKV sourceKv = MMKV.mmkvWithID("source_data", MMKV.SINGLE_PROCESS_MODE);

257

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

258

259

long importedCount = targetKv.importFrom(sourceKv);

260

Log.d("MMKV", "Imported " + importedCount + " items to multi-process instance");

261

262

// Migrate from SharedPreferences to multi-process MMKV

263

SharedPreferences oldPrefs = getSharedPreferences("old_prefs", MODE_PRIVATE);

264

MMKV newKv = MMKV.mmkvWithID("migrated_data", MMKV.MULTI_PROCESS_MODE);

265

266

int migratedCount = newKv.importFromSharedPreferences(oldPrefs);

267

Log.d("MMKV", "Migrated " + migratedCount + " preferences to MMKV");

268

```

269

270

### Parcelable MMKV for Process Communication

271

272

Use ParcelableMMKV to pass MMKV instances across process boundaries via Binder.

273

274

```java { .api }

275

/**

276

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

277

*/

278

public final class ParcelableMMKV implements Parcelable {

279

/**

280

* Create ParcelableMMKV from MMKV instance.

281

* @param mmkv The MMKV instance to wrap

282

*/

283

public ParcelableMMKV(MMKV mmkv);

284

285

/**

286

* Convert back to MMKV instance.

287

* @return The MMKV instance, or null if invalid

288

*/

289

public MMKV toMMKV();

290

291

// Parcelable implementation

292

public int describeContents();

293

public void writeToParcel(Parcel dest, int flags);

294

public static final Creator<ParcelableMMKV> CREATOR;

295

}

296

```

297

298

**Usage Example:**

299

300

```java

301

// Create ashmem MMKV for cross-process sharing

302

MMKV ashmemKv = MMKV.mmkvWithAshmemID(

303

this, "cross_process_data", 512 * 1024, MMKV.MULTI_PROCESS_MODE, null

304

);

305

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

306

307

// Wrap in Parcelable for IPC

308

ParcelableMMKV parcelableKv = new ParcelableMMKV(ashmemKv);

309

310

// Send via Intent to another process/activity

311

Intent intent = new Intent(this, OtherProcessActivity.class);

312

intent.putExtra("mmkv_instance", parcelableKv);

313

startActivity(intent);

314

315

// In receiving process/activity

316

ParcelableMMKV receivedParcelable = getIntent().getParcelableExtra("mmkv_instance");

317

if (receivedParcelable != null) {

318

MMKV receivedKv = receivedParcelable.toMMKV();

319

if (receivedKv != null) {

320

String message = receivedKv.decodeString("shared_message", "");

321

Log.d("MMKV", "Received: " + message);

322

}

323

}

324

```

325

326

### Multi-Process Best Practices

327

328

```java

329

// 1. Always use MULTI_PROCESS_MODE for shared data

330

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

331

332

// 2. Use locking for critical sections

333

sharedKv.lock();

334

try {

335

// Atomic read-modify-write operations

336

int counter = sharedKv.decodeInt("counter", 0);

337

sharedKv.encode("counter", counter + 1);

338

} finally {

339

sharedKv.unlock();

340

}

341

342

// 3. Monitor content changes from other processes

343

MMKV.registerContentChangeNotify(mmapID -> {

344

// Refresh data when other processes make changes

345

refreshLocalCache();

346

});

347

348

// 4. Use try-lock for non-critical operations

349

if (sharedKv.tryLock()) {

350

try {

351

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

352

} finally {

353

sharedKv.unlock();

354

}

355

}

356

357

// 5. Separate single-process and multi-process data

358

MMKV localKv = MMKV.mmkvWithID("local_cache", MMKV.SINGLE_PROCESS_MODE); // Faster

359

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

360

```

361

362

## Types

363

364

```java { .api }

365

public interface MMKVContentChangeNotification {

366

/**

367

* Inter-process content change notification.

368

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

369

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

370

*/

371

void onContentChangedByOuterProcess(String mmapID);

372

}

373

374

public final class ParcelableMMKV implements Parcelable {

375

public ParcelableMMKV(MMKV mmkv);

376

public MMKV toMMKV();

377

public int describeContents();

378

public void writeToParcel(Parcel dest, int flags);

379

public static final Creator<ParcelableMMKV> CREATOR;

380

}

381

```

382

383

## Constants

384

385

```java { .api }

386

public static final int SINGLE_PROCESS_MODE = 1 << 0; // Single-process mode (default)

387

public static final int MULTI_PROCESS_MODE = 1 << 1; // Multi-process mode

388

public static final int READ_ONLY_MODE = 1 << 5; // Read-only mode

389

```