5

I have to work with IBinders and Parcels. I've gone through all of the IBinder, Binder, and Parcel documentation and could not find anything which talks about when to call Parcel.recycle (I also never read anything that said that a parcel must be recycled). I've seen examples like the following:

void someMethod(IBinder binder) {
  final int code = // ...
  final Parcel data = Parcel.obtain()
  final Parcel reply = Parcel.obtain()

  try {
    binder.transact(code, data, reply, 0);
  } finally {
    data.recycle();
    reply.recycle();
  }
}

But the thing that confuses me is that in every example, I do NOT see this:

class MyBinder extends Binder {
  @Override
  public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {

    try {
      // do things...
    } finally {
      data.recycle();
      // calling reply.recycle() doesn't make sense because it has to be sent
      // back to the client
    }

  }
}

Does this mean that calling recycle will recycle the parcel on both the ends of the connection? Or are the data and reply parcels (in the onTransact method) just recycled behind the scenes when onTransact method exits.

And if someone does have the answer, where did you find it out from? Is there some sort of secret book or website that documents this? I can't find it anywhere on https://developer.android.com

Ideally what I would like to do is get the data parcel from onTransact and pass it into a task inside of a thread pool. But because I don't know when (or if) the parcel gets recycled, I don't know when (or if) I can use the data parcel.

1 Answers1

0

in every example, I do NOT see this

That is expected. It would be the responsibility of the caller of onTransact() to recycle its Parcel. After all, onTransact() has no idea if the caller intends to reuse that Parcel instance.

Does this mean that calling recycle will recycle the parcel on both the ends of the connection?

AFAIK, no.

Or are the data and reply parcels (in the onTransact method) just recycled behind the scenes when onTransact method exits.

Yes.

And if someone does have the answer, where did you find it out from?

I looked at the source code to Binder, where onTransact() is being called. The finally block recycles the Parcel instances.

Ideally what I would like to do is get the data parcel from onTransact and pass it into a task inside of a thread pool. But because I don't know when (or if) the parcel gets recycled, I don't know when (or if) I can use the data parcel.

Since the Parcel is recycled, that is not safe. You will want to grab the data out of that Parcel and put it in something else that you put in your thread pool.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491