I was testing my app on Android Nougat, and it crashed when I try to move from one Activity to another. I saw this in the log: java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 700848 bytes.
Actually, the platform has been printing warning log about this for a while, but let's be honest, who has time to read all the logs? Nougat (API 24) throws TransactionTooLargeExceptions as RuntimeExceptions, so we cannot ignore that any more.
onSaveInstanceState
Turns out I was saving a big list of search results during onSaveInstanceState to persist them over rotation. Time to move that to a Loader!
But what is the limit?
But now I'm curious: What is the limit? I wrote a sample app to find out.
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, AnotherActivity.class);
startActivity(intent);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
int length = 1000;
Uri uri = getIntent().getData();
if (uri != null) {
try {
length = Integer.parseInt(uri.getLastPathSegment());
} catch (NumberFormatException e) {
}
}
byte[] data = new byte[length];
outState.putByteArray("data", data);
}
}
To try different sizes, I start the app like this:
adb shell am start \ -a android.intent.action.View \ -n com.sqisland.tutorial.transcation_too_large/.MainActivity \ -d 700000
This launches MainActivity, which immediately goes to AnotherActivity. When that happens, the system calls onSaveInstanceState, which tries to stash away a byte array of the length specified in the adb command, retrieved by getIntent().getData(). This way, I can try different numbers without recompiling and redeploying the app.
I did a binary search on a Nougat emulator and my Nexus 9. The limit is slightly different, but it hovers around 500000. That is not a small number, but not too hard to exceed if you try to store data rather than state.
