web-dev-qa-db-ja.com

Parcelableでのフラグの使用は何ですか?

メソッドシグネチャのパラメータであるフラグフィールドに焦点を当てずにParcelablesを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);
            }
        }
    }
_

これは私が書いたMapto/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フラグとは何か、どのように使用すべきかを簡単に説明できる人はいますか?

13
pulp_fiction

現在存在する唯一のフラグ(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以外では実際には広く使用されていないため、そのようなフラグの例はありません。

5
user1643723

フラグ0または1のみを指定できます。

Voidメソッドがあるので、関数からParcelableを返したり、ドキュメントにあるようにParcelableのパラメーターを持ったりしないので、フラグはゼロにする必要があります。

0
cricket_007