Androidの根幹をなすInetntによるメッセージングを支える技術として「Parcel」「Parcelable」というものが存在します。これは、普通にAndroidアプリを作成していても特に気が付かないかもしれませんが、とても多くの場所で使われています。
誤解を恐れずに簡潔に説明すると、ParcelableはJavaの「Serializable」で、ParcelはParcelable専用のストリームです。Parcelは、カーネルを経由してプロセス間で受け渡しされるデータを抽象化したクラスです。
Parcelというのは日本語では「小包」という意味で、Androidにおいては小さいデータを意味します(具体的にはデータが128bytes以内であれば、データコピーのオーバーヘッドが抑えられるように設計されています)。
■ Parcelのメソッド
Parcelには、データを書き込む「writeXxx」というメソッドと、書き込んだデータを読み出す「readXxx」というメソッドが存在します。
書き込まれたデータはJavaヒープの外にバイト配列として展開されます。データが追加されるたびに「realloc」で領域が確保されます。Javaヒープの外にデータを保持するのは、プロセス間通信でカーネルモジュールがダイレクトにアクセスできるようにするためです。
Parcelには、「marshall()」「unmarshall(byte[], int, int)」が用意されており、それぞれ、Parcelをbyte[]に変換するメソッドと、byte[]からParcelに変換するメソッドです。これらのメソッドはParcelableをバイト配列に変換したり、バイト配列からParcelableに戻したりできるため、プロセス間通信以外でも便利に使えます。
■ Parcelは永続化やマシン間通信には使用しないように
ただ残念ながら、Parcelableが入れ子になっていると、marshall()が行えない(例外が発生する)という制限が存在します。Parcelを使用すると、制限の範囲内でインスタンスをストレージに保存して永続化可能です。
ただしParcelは、あくまでもプロセス間通信などの一時的なデータの受け渡しに使うことを想定しており、将来的なデータフォーマットの互換を保証するものではないため、Javadocでは永続化やマシン間通信には使用しないように忠告しています。
■ ParcelとAIDLで扱えるデータ型
Parcelに読み書き可能なデータ型は、AIDL同様に制限されています。以下の表は、ParcelとAIDLで扱えるデータ型の一覧です。
|
ParcelやAIDLでは、charやshortなど、すべてのプリミティブ型ないしプリミティブ配列型をサポートしていないことに注意してください。
ParcelとAIDLでは、サポートする型に違いがあり、AIDLの方が若干少ないです。しかし、Parcelableを実装した独自コンテナではParcelを直接扱え、AIDLはParcelableが扱えるため、実質Parcelで扱える型のすべてがプロセス間通信で扱えるようになります。
0 件のコメント:
コメントを投稿