1

I am sending data via broadcasts like this:

Intent outIntent = new Intent(Const.ACTION_FEED);
outIntent.putExtra(Const.EXTRA_FEED, data);
sendBroadcast(outIntent);

The issue is that data can get quite large, resulting in a TransactionTooLargeException. The documentation says:

The Binder transaction buffer has a limited fixed size, currently 1Mb, which is shared by all transactions in progress for the process. Consequently this exception can be thrown when there are many transactions in progress even when most of the individual transactions are of moderate size.

Bottom line: it seems to be impossible to tell in advance what size is acceptable for data.

Furthermore:

The key to avoiding TransactionTooLargeException is to keep all transactions relatively small. [...] If possible, try to break up big requests into smaller pieces.

The nature of the data I am sending is such that I could easily break it down into smaller pieces and send them individually, once I have established that the whole thing is too big to send at once.

The logical step would be to wrap the whole code in a try/catch block, and upon receiving a TransactionTooLarge exception, chop up the data into smaller chunks and retry.

Alas, according to the logcat, the exception is not thrown at the caller’s end but in a system process. The system then goes on to crash the receiver of the broadcast, at which point any recovery is out of the sender’s control.

How can I tell how much data is OK to send as a broadcast extra, and prevent crashing the receiver of the data?

user149408
  • 5,385
  • 4
  • 33
  • 69
  • "I am sending data via broadcasts" -- why? What app is going to receive this broadcast? How are you going to prevent all the other apps from receiving this broadcast? How are you planning on getting past the problem that your broadcast will not work on Android 8.0+, as there is a ban on implicit broadcasts? – CommonsWare Jul 19 '19 at 21:58
  • 1
    Assuming the receiver is in your app, you're probably better off using an event bus, or using rxjava as an event bus. If you're sending it to something outside your app, you probably need to send it a uri to the data, and provide a ContentProvider it can query with that uri for the data. – Gabe Sechan Jul 19 '19 at 22:13
  • @CommonsWare Any interested app can receive the broadcast as long as it has location permission (as the only sensitive information in the data allows for conclusions about the device’s location). This is intended as an open interface with multiple senders and receivers, which might not even know about each other. Receivers need to register a `BroadcastReceiver` at runtime so it will pick up implicit broadcasts. – user149408 Jul 19 '19 at 22:35
  • "Any interested app can receive the broadcast as long as it has location permission" -- you are not doing anything in that broadcast to impose such a limitation, at least based on the code in your question. Beyond that, I agree with Gabe's recommendation of using something else for bulk data transfer, where a `ContentProvider` is a reasonable choice. As a bonus, you can defend that provider with the `ACCESS_FINE_LOCATION` permission, solving the permission problem at the same time, since the broadcast itself, with just the `Uri`, would contain no private data. – CommonsWare Jul 19 '19 at 22:37
  • 1
    @CommonsWare re limitations, indeed, I left that out in the question for simplicity. The actual code specifies permissions for the broadcast. – user149408 Jul 19 '19 at 22:42

0 Answers0