Android シリアル化のパーセル概要 (1)

記事ディレクトリ

1. シリアル化された分類

Android には 2 つのシリアル化方法がありますSerializableParcelable

Serializable : Java 独自のインターフェイス。このインターフェイスを実装することでオブジェクトをシリアル化できます。IO を使用してシリアル化されたオブジェクトをハードディスクに保存するための読み取りと書き込みを行うと、読み取りと書き込みの速度が遅くなります。シリアル化のプロセスではリフレクション技術が使用されるため、多数の一時オブジェクトが生成され、大きな領域を占有します。ただし、その利点はコードが簡単であることです。開発者は Serializeable を実装するだけでよく、オブジェクトにはシリアル化と逆シリアル化の機能があります。
Parcelable : Android の独自のインターフェイスであり、Serializable よりもパフォーマンスが優れています。原則は完全なオブジェクトを分解 (フラット化) することであり、分解後の各部分は Intent がサポートするデータ型になります。メモリに直接読み書きする方法です。メモリの読み書き速度がハードディスクよりも速いため、Serializableよりもパフォーマンスが高くなります。デメリットは、エンコードが面倒なことです。 Serializable メソッドよりも。

選び方:

アクティビティとサービスの間で情報を転送するなど、メモリ内でのみ使用される場合は、Parcelable を使用することを強くお勧めします。これは、Parcelable の方が Serializable よりもパフォーマンスが高く、Serializable はシリアル化中に大量の一時変数を生成するため、頻繁なエラーが発生するためです。 GC。
永続的な操作の場合は Serializable を使用することをお勧めしますが、Parcelable は効率は比較的低いですが、外界が変化した場合にデータの永続性をうまく保持できません。

2.連載

Android システムは Linux システムに基づいて実装されており、Linux にはプロセス分離メカニズムがあることがわかっています。ただし、プロセスが複雑なデータ型を渡す場合、オブジェクトへの参照 (本質的にはメモリ アドレス) が渡されます。Linux は仮想メモリ機構を使用しているため、両方のプロセスが独自の独立したメモリ アドレス空間を持っているため、A プロセスのオブジェクトのメモリ アドレスを B プロセスに渡します。この 2 つのプロセスでメモリ アドレスがマッピングされる物理メモリ アドレスは同じではないため、通信を実現するには、前述のシリアル化メソッドに依存してオブジェクトのバイト シーケンスを転送する必要があります。

Parcel はメッセージを保持するためのコンテナであり、データ送信のための Binder メカニズムを受信するために使用されます。シリアル化されたデータを IPC 経由で伝送し、宛先で逆シリアル化できます。Parcel は IBinder オブジェクトを渡すこともでき、宛先側は送信された IBinder オブジェクトのプロキシを受信します。Parcel 内のデータの基盤となる実装が変更されると、古い値が使用できなくなる可能性があるため、Parcel は永続ストレージには適していません。また、それはメモリ内に実装されており、メモリ内の永続データは信頼できません。
ここに画像の説明を挿入

  • Android システム レベルから見ると、Android システムの Binder メカニズムによって実装された IPC は、Parcel クラスを使用してクライアントとサーバー間のデータ対話を実行します。また、Parcel は Java 層と cpp 層の両方 (JNI アソシエーション経由) に実装されます。c/cpp ではメモリを直接使用してデータを読み取るため、より効率的です。
  • ストレージの観点から見ると、Parcel は単なる連続したメモリの一部にすぎません。必要に応じてサイズが自動的に拡張されます。

小包転送データタイプ:

  • 基本データ型: Parcel->writePrimitives() を使用して、基本データ型をユーザー空間 (ソース プロセス) からカーネル空間 (バインダー ドライバー内) にコピーし、ユーザー空間 (ターゲット プロセス、バインダー ドライバーがターゲットを見つける責任があります) に書き戻します。プロセス)

  • 複雑なデータ型: Parcel->writeParcelable()/writeSerializable() を使用して、シリアル化されたデータをユーザー空間 (ソース プロセス) からカーネル空間 (バインダー ドライバー内) にコピーし、それをユーザー空間 (ターゲット プロセス、バインダー ドライバー内) に書き戻します。逆シリアル化の前にターゲット プロセスを見つける責任があります。

  • ビッグデータ: 匿名共有メモリ (Ashmem) の FileDescriptor を Parcel->writeFileDescriptor() を介して Binder に渡し、匿名共有メモリを渡す方法を実現します。つまり、実際のビッグデータの代わりに FileDescriptor が渡されます。Android 匿名共有メモリの使用を参照してください。

  • IBinder オブジェクト: Parcel->writeStrongBinder() を呼び出すことにより、カーネル バインダー ドライバーによる特別な処理を通じて IBinder 転送が完了します。ターゲット プロセスは、IBinder オブジェクトへのプロキシを受け取ります。

参考:

https://blog.csdn.net/wenhonglian/article/details/125487162

おすすめ

転載: blog.csdn.net/wangadping/article/details/128173285