使用 LocalBroadcastManager 发送 PendingResult 参考(用于有序广播)

Use LocalBroadcastManager to send PendingResult reference (for ordered broadcasts)

我想通过 LocalBroadcastManager 发送 PendingResult,因为 LocalBroadcastManager 似乎不支持有序广播。

我可以制作一个实现 Parcelable 的包装器对象,它包含对 PendingResult 的内存引用,然后将其粘贴到 Intent(根本没有任何序列化)吗?真正的问题是:当使用 LocalBroadcastManager 通过 Intent 发送 Parcelable 时,对象内存引用是否完好无损,即 LocalBroadcastManager 是否真的只将 Intent 对象引用转发到我的应用程序中的不同位置?

有更好的方法吗?

这可以通过 Android Hidden API library ResourcesHolder class 完成。尽管该库是为访问内部 API 而设计的,但是发送任何对象都是它的能力之一。看这个例子:

ResourcesHolder holder = new ResourcesHolder()
    // you also able to put multi-object, but give each of them different 'key'
    .put("pi1", myPendingIntent1)
    .put("pi2", myPendingIntent2);

// send via context.sendBroadcast(intent)
holder.sendBroadcast(context, "myKey");

// or send via LocalBroadcastManager
holder.sendViaLocalBroadcastManager(context, "myKey");

// don't forget to register your receiver with IntentFilter ResourcesHolder.ACTION_SEND_RESOURCES_HOLDER

在你的BroadcastReceiver中:

// to get them back:
if (intent.getAction().equals(ResourcesHolder.ACTION_SEND_RESOURCES_HOLDER){
    ResourcesHolder holder = intent.getParcelableExtra("myKey");
    PendingIntent pi1 = (PendingIntent) holder.getAsObject("pi1");
    PendingIntent pi2 = (PendingIntent) holder.getAsObject("pi2");
}

我为 PendingResult 制作了一个 Parcelable 包装器:

public class PendingResultWrapper implements Parcelable {

    private BroadcastReceiver.PendingResult pendingResult; //The only thing we care about in this class!

    public PendingResultWrapper(BroadcastReceiver.PendingResult pendingResult) {
        this.pendingResult = pendingResult;
    }

    protected PendingResultWrapper(Parcel in) {
    }

    public static final Creator<PendingResultWrapper> CREATOR = new Creator<PendingResultWrapper>() {
        @Override
        public PendingResultWrapper createFromParcel(Parcel in) {
            return new PendingResultWrapper(in);
        }

        @Override
        public PendingResultWrapper[] newArray(int size) {
            return new PendingResultWrapper[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
    }

    public BroadcastReceiver.PendingResult getPendingResult() {
        return pendingResult;
    }

}

它可以绑定到 Intent 并由 LocalBroadcastManager 作为对象引用进行广播,因为本地广播从未真正序列化,这与进程间广播不同。

有效!