メソッドシグネチャのパラメータであるフラグフィールドに焦点を当てずにParcelable
sをParcel
に書き込んでいますが、正常に機能しましたが、無視できない実装に遭遇しました。それら:
_public static <K extends Parcelable, V extends Parcelable> void write(Parcel dest,
Map<K, V> map, int flags) {
if (map == null) {
dest.writeInt(-1);
} else {
Set<Map.Entry<K, V>> entrySet = map.entrySet();
dest.writeInt(entrySet.size());
for (Map.Entry<K, V> entry : entrySet) {
dest.writeParcelable(entry.getKey(), flags);
dest.writeParcelable(entry.getValue(), flags);
}
}
}
_
これは私が書いたMap
to/fromParcelable
ユーティリティであり、フラグをそのまま両方に渡す必要があるかどうか疑問に思っていますKeyおよびValueを書き込むか、Keyに0を渡す必要がありますおよびflags
forValue。
docs にあるフラグの定義を読みました:
PARCELABLE_WRITE_RETURN_VALUE
APIレベル1に追加
_int PARCELABLE_WRITE_RETURN_VALUE
_
writeToParcel(Parcel, int)
で使用するフラグ:書き込まれるオブジェクトは戻り値です。これは、"Parcelable someFunction()"、"voidなどの関数の結果です。 someFunction(out Parcelable) "、または" void someFunction(inout Parcelable) "。一部の実装では、この時点でリソースを解放したい場合があります。定数値:1(0x00000001)
しかし、それを理解することはできません。 Parcelable
フラグとは何か、どのように使用すべきかを簡単に説明できる人はいますか?
現在存在する唯一のフラグ(PARCELABLE_WRITE_RETURN_VALUE
)は [〜#〜] aidl [〜#〜] インターフェースでの使用を目的としています。特定の種類のParcelableオブジェクトがIPCメソッドから返されるため、関連するリソースを解放できることを示唆することになっています。たとえば、ContentProviderには、次のようなAIDLメソッドが内部に含まれています。
ParcelFileDescriptor openFile(String path, int flags);
カスタムContentProviderでopenFile
をオーバーライドすると、メソッドはopenParcelFileDescriptorを返します…自分で閉じているのではなく、プロセス間転送中にも自動的に閉じられません(プロセス間で記述子を渡すことは、Linuxでそれらを閉じることを意味しません)。しかし、記述子はリークされていません!代わりに、ParcelFileDescriptor それ自体を閉じる Parcelに書き込まれると:
@Override
public void writeToParcel(Parcel out, int flags) {
if (mWrapped != null) {
try {
mWrapped.writeToParcel(out, flags);
} finally {
releaseResources();
}
} else {
if (mCommFd != null) {
out.writeInt(1);
out.writeFileDescriptor(mFd);
out.writeFileDescriptor(mCommFd);
} else {
out.writeInt(0);
out.writeFileDescriptor(mFd);
}
if ((flags & PARCELABLE_WRITE_RETURN_VALUE) != 0 && !mClosed) {
// Not a real close, so emit no status
closeWithStatus(Status.SILENCE, null);
}
}
}
ParcelFileDescriptorは単なる通常のクラスであり、Binder/Parcelの機能を使用してプロセス間でFileDescriptorを渡すため、ネイティブリソース(メモリ、ファイル記述子)を保持し、openFileのようなメソッドから返されるときに条件付きで解放する同様のクラスの存在を想像できます。
同様に、他のフラグcouldを使用して、同様の条件付き動作をParcelablematryoshkaの奥深くに伝播できます。残念ながら、Android開発者は、そのようなカスタムフラグを導入するための合理的なルールを定義していません(例:IBinder#FIRST_CALL_TRANSACTION
およびIBinder#LAST_CALL_TRANSACTION
)、AIDLはAndroid internals以外では実際には広く使用されていないため、そのようなフラグの例はありません。
フラグ0または1のみを指定できます。
Voidメソッドがあるので、関数からParcelableを返したり、ドキュメントにあるようにParcelableのパラメーターを持ったりしないので、フラグはゼロにする必要があります。