Android の MMKV ストレージ フレームワーク

1. mmkv使用オペレーションコード

重要なのは、最初の章の 1、2、3、4 の操作方法だけを知っていればよく、それ以降の操作方法を理解する必要はないということです。

1. まず、mmkv パッケージを導入し、次のコンテンツを build.gradle に追加する必要があります。

implementation 'com.tencent:mmkv-static:1.2.7'

2. 次に、カスタム アプリケーションに初期化コンテンツを追加する必要があります (onCreate メソッドに置きます)。

MMKV.initialize(this);

3. カスタム mmkv オブジェクト

MMKV mmkv2 = MMKV.mmkvWithID("id");

MMKV はデフォルトで単一プロセスをサポートします。ビジネスでマルチプロセス アクセスが必要な場合は、初期化中にマルチプロセス モード パラメータを追加する必要があります: MMKV.MULTI_PROCESS_MODE

MMKV mmkv3 = MMKV.mmkvWithID("myId",MMKV.MULTI_PROCESS_MODE);//多进程同步支持

4.保管方法

//1.添加或者更新数据
//可以通过 encode() 方式存储数据也可以使用和 SharedPreferences 相同的 put() 方式存储数据;
kv.encode("name", "阿策小和尚");
kv.putInt("sex", 0);
 
//2.获取数据,同样可以采用 decodeXXX() 或 getXXX() 获取数据;
//获取boolean类型数据
boolean bValue = kv.decodeBool("bool");
kv.getString("address", "");
 
//3.删除数据,移除指定的key
kv.remove("bool");//remove函数调用removeValueForKey方法
kv.removeValueForKey("bool");
System.out.println("bool: " + kv.decodeBool("bool"));
// 移除一组key
kv.removeValuesForKeys(new String[]{
    
    "int", "long"});
String s1=Arrays.toString(kv.allKeys());
//kv.allKeys()方法获取数组返回所有的key,Arrays.toString方法把数组内容打印出来
//查询是否有这个键值对
boolean hasBool = kv.containsKey("bool");
 
//4.与SharedPreferences 一样,remove() 清除一条数据,clear() 清空全部数据;
kv.clear();

オブジェクトにアクセスする必要がある場合は、オブジェクトの json 文字列にアクセスしてオブジェクトを json に変換して保存し、json を取り出してオブジェクトに変換する方法を使用できます。
実際の Android プロジェクトのコード:

String spInfo = GISApplication.MMKVStorage.getString(KEY_SURVEY_POINT_DTO, "");
GISApplication.MMKVStorage.putString(GlobalConstant.KEY_SURVEY_POINT_DTO, "");
//GISApplication是安卓项目中的自己创建的Application,MMKVStorage是定义的一个MMKV类型的变量

5. ファイルの保存場所

MMKV は、デフォルトで $(FilesDir)/mmkv/ ディレクトリにファイルを保存します。MMKV の初期化時にルート ディレクトリをカスタマイズできます。

String dir = getFilesDir().getAbsolutePath() + "/mmkv";
String rootDir = MMKV.initialize(dir);

6.mmkv は SP データを移行することもできます

MMKV は、SP データを移行するために importFromSharedPreferences メソッドを呼び出すことができます。サンプル コードは次のとおりです:
MMKV は SharedPreferences および Editor インターフェイスを実装しているため、移行後に SP オペレーション コードを変更する必要はありません。

MMKV kv = MMKV.mmkvWithID("myData");
SharedPreferences olderData = App.getInstance().getSharedPreferences("myData", MODE_PRIVATE);
kv.importFromSharedPreferences(olderData);
olderData.edit().clear().apply();    //删除其中的所有数据

2.共有設定

1. まず SharedPreferences について話しましょう. データはキー/値 (キーと値のペア) の形式で XML ファイルに保存されますが、一部のファイルはプロセスをまたがることができません。したがって、ここでは使用せず、ストレージには mmkv を使用します。mmkv については後ほど説明します。

3. mmkvの詳しい説明

1.mmkvの紹介

MMKV は、それぞれ、mmap メモリ マッピングに基づくキーと値のコンポーネントであるメモリ マッピング キー値を表します。基礎となるシリアル化/逆シリアル化は、protobuf を使用して実装されます。高性能、強力な安定性があり、適切に置き換えることができる SP ストレージです。これは現在 WeChat で使用されている軽量のストレージ フレームワークであり、Android / macOS / Win32 / POSIX を含む複数のプラットフォームでオープンソース化されています。

2.mmkvの利点

(1) データ形式と更新範囲の最適化: SharedPreferences は XML データ ストレージを使用し、各読み取りおよび書き込み操作はグローバルに更新されます。mmkv は protobuf データ ストレージを使用し、値をエンコード/デコードするため、よりコンパクトでローカル更新をサポートします。

(2) 時間のかかるファイル操作の最適化: mmkv は mmap を使用してファイルとのメモリ同期を維持し、MMap メモリ マッピングを使用して I/O 操作を置き換え、0 コピー テクノロジを使用して更新速度を向上させ、最適なパフォーマンスを実現します。

(3) マルチプロセスの同時実行: MMKV は、プロセス間の同時読み取りおよび書き込みアクセスをサポートします。

(4) 使いやすい: mmkv はいつでも使用できます。すべての変更はすぐに保存され、同期や適用呼び出しは必要ありません。

(5) 小さい。いくつかのファイル: MMKV には、プロセス ロック、エンコード/デコード ヘルパー、mmap ロジックなどが含まれています。とてもきちんとしています。約 60K のバイナリ サイズ: MMKV は、各アーキテクチャでアプリケーション サイズに約 60K 追加しますが、圧縮 (apk) するとさらに小さくなります。

(6) クロスプロセス ステータスの同期: SharedPreferences は、スレッド セーフのためのクロスプロセス ステータスの同期をサポートしていません。MMKV は、CRC チェックとファイル ロック ロックを通じてクロスプロセス ステータスの更新を実装します。

(7) 代替 SP と比較した利点と要件: データ暗号化、マルチプロセス共有、匿名メモリ、高効率。

3.MMKV原理

(1) メモリの準備: mmap メモリ マッピング ファイルを通じて、いつでも書き込むことができるメモリ ブロックが提供されます。アプリはそこにデータを書き込むだけで、オペレーティング システムはメモリをファイルに書き戻す責任を負います。クラッシュによるデータ損失を心配する必要はありません。
(2) データ構成: データのシリアル化には protobuf プロトコルを使用しており、pb はパフォーマンスとスペース使用量の点で優れています。
(3) 書き込みの最適化: 主な使用シナリオが頻繁な書き込み更新であることを考慮すると、増分更新する機能が必要です。インクリメンタル kv オブジェクトをシリアル化し、メモリの最後に追加することを検討します。
(4) スペースの増大: 追加を使用して増分更新を実装すると、新たな問題が発生します。つまり、追加を継続するとファイル サイズが制御不能に増大します。パフォーマンスとスペースの間で妥協する必要があります。

4.メモリマッピング メモリマッピング

mmap と呼ばれるメモリ マッピングは、ファイルをメモリ マッピングする方法であり、ディスク上のファイルまたはその他のオブジェクトの一部または全体をプロセス (アプリケーション) のアドレス空間にマッピングし、ファイルのディスク アドレスとプロセス仮想アドレス空間内の仮想アドレス 1 対 1 の対応により、アプリケーションはメモリにアクセスすることでディスク ファイルにアクセスできます。

ここに画像の説明を挿入します
mmap の利点は明白であることがわかります。メモリ マッピングにより、プロセスはポインタを使用してオペレーティング メモリの読み書きを行うことができます。システムはダーティ ページを対応するファイル ディスクに自動的に書き戻します。オペレーティング メモリはオペレーティング ファイルと同等です。新しいスレッドを開始する必要はなく、カーネル空間のこの領域への変更はユーザー空間に直接反映されるため、異なるプロセス間でのファイル共有が可能になります。I/O と比較すると、ファイルの読み取りおよび書き込み操作では、ディスクからユーザーのメイン メモリへのデータ コピー プロセスが 1 回だけ必要となるため、データ コピーの数が減り、ファイル操作の効率が向上します。同時に、mmap は、次のセクションを提供するだけで済みます。メモリが必要なだけです。メモリ ファイルの読み取りおよび書き込み操作に集中してください。オペレーティング システムがメモリを使い果たすか、プロセスが終了すると、メモリは自動的にファイルに書き込まれます。メモリをファイルに書き戻すのはオペレーティング システムの責任です。 . クラッシュによるデータ損失を心配する必要はありません。

もちろん、mmap には独自の欠点もあります。mmap は 1 度の長さのメモリ ブロックを提供する必要があるためです。そのマッピング領域のデフォルトの長さは 1 ページ、つまり 4kb です。保存されているファイルの内容が小さい場合は、スペースの無駄を引き起こす。

4.プロトコルバッファのエンコード構造

プロトコル バッファー (略して protobuf) は、Google によって生成されたシリアル化されたデータの拡張可能なエンコード形式です。Google によって開発されたプロトコルで、構造化データのシリアル化と逆シリアル化を可能にします。これは単なるメッセージ形式ではなく、一連のルールですこれらのメッセージを定義および交換するためのツール。主に通信プロトコルとデータ ストレージに使用され、バリント原理 (値が小さいほど使用されるバイト数が少なくなる可変長符号化方式) を使用してデータを圧縮すると、バイナリ データは非常にコンパクトになります。

Google は、システム間の通信に XML よりも優れた方法を提供するためにこれを開発しました。このプロトコルは JSON をも上回り、パフォーマンス、保守性が向上し、サイズが小さくなります。

protobuf は TLV (TAG-Length-Value) エンコード形式を採用しており、これにより区切り文字の使用が減り、エンコードがよりコンパクトになります。protobuf がファイルを更新するとき、
ここに画像の説明を挿入します
部分的な更新には不便ですが、段階的に更新できます。以前に同じキーが存在するかどうかに関係なく、ファイルの最後に新しいデータが追加されると、最終ファイルが読み取られるときに、新しいデータが古いデータを上書きします。

新しいデータを追加する場合、ファイル サイズが十分ではないため、完全に更新する必要があります。このとき、Map 内のデータは MMKV 方式に従ってシリアル化し、必要なバイト数にフィルタリングして保存し、比較する必要があります。取得したバイト数に基づいてファイルサイズを変更; 保存されたファイルサイズが新しいデータを追加できる場合は、最後に直接追加します; 保存されたファイルサイズがまだ新しいデータを追加するには十分ではない場合は、protobuf * 2 を拡張する必要があります現時点では;

protobuf は機能が単純で、バイナリストレージとして可読性が低いと同時に、複雑な概念を表現できず、汎用性が xml に劣るという欠点もあります。

5.flock ファイルロック + CRC チェック

SharedPreferences はスレッド セーフのため複数プロセスでのデータ更新をサポートしませんが、MMKV はフロック ファイル ロックと CRC 検証を通じてマルチプロセスの読み取りおよび書き込み操作をサポートします。

Xiaocai は、MMKV がプロセス A でデータを更新したことを単純に理解しています。プロセス B で現在のデータを取得するとき、まず CRC ファイルを通じてファイルが更新されたかどうかを確認します。更新されていない場合は、直接読み取ります。更新されている場合は、ファイルの内容が再取得されます。読み取り中です。

複数のプロセスが同時にファイルに書き込むのを防ぐために、MMKV はファイル ロック flock メソッドを使用して、同時に 1 つのプロセスだけがファイルに書き込むようにします。

ファイル ロックには本来堅牢であるという利点がありますが、欠点は再帰的ロックをサポートしておらず、読み取り/書き込みロックのアップグレード/ダウングレードもサポートしていないため、自分で実装する必要があることです。

おすすめ

転載: blog.csdn.net/zxz_zxz_zxz/article/details/130734095