androidandroid-bitmapparcelableaidlandroid-binder

Why DeadObjectException during AIDL call using byte[] but not Bitmap?


Let's say there are two processes. I am interested in making an AIDL call (e.g. byte[] getBytes()) from an Activity (Process A) to a Service (Process B) which returns a byte[] of data.

However when this byte[] of data exceeds 1MB, it triggers the following expected exception. This also happens if the byte[] is wrapped inside of a custom Parcelable class.

W Error = android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died
W   at android.os.BinderProxy.transactNative(Native Method)
W   at android.os.BinderProxy.transact(BinderProxy.java:571)

This appears to be caused by the data limits documented here: https://developer.android.com/guide/components/activities/parcelables-and-bundles

However, if the AIDL API returns a Bitmap (e.g. Bitmap getBitmap() ) containing data for an image that exceeds 1MB, this exception does not get triggered. Why does it work? In general, if I'd like to send data over 1MB, what would be the preferred method? In this test case, it's using an image file for the Bitmap but what if it is an audio file, video file or something else?


Solution

  • It depends. An implementation of Bitmap may not contain all of the image data in an array- it may contain information needed to get that data. For example, it may contain the filename of an image, and accessing the data would try to reopen the file. (whether that would work would depend on access rights of both apps). Or provide the URI of a content provider it can query for the data. Could that technique work with other data? Yes, if there's a reasonable way to do that. But there needs to be a way for the receiving app to reacquire the full data set.

    However the 1MB limit to the size of a Bundle (the underlying class used to send data via AIDL) is hardcoded at the OS level. You can't get around it and put more in the bundle. You can only do a misdirection like this.