I got in error track of an app TransactionTooLargeException. Not reproducible and never had it before. In the docs it says
The Binder transaction failed because it was too large.
During a remote procedure call, the arguments and the return value of the call are transferred as Parcel objects stored in the Binder transaction buffer. If the arguments or the return value are too large to fit in the transaction buffer, then the call will fail and TransactionTooLargeException will be thrown.
...
There are two possible outcomes when a remote procedure call throws TransactionTooLargeException. Either the client was unable to send its request to the service (most likely if the arguments were too large to fit in the transaction buffer), or the service was unable to send its response back to the client (most likely if the return value was too large to fit in the transaction buffer).
...
So, ok, somewhere I'm passing or receiving arguments which exceed some unknown limit. But where?
The stacktrace doesn't show anything from my files:
java.lang.RuntimeException: Adding window failed
at android.view.ViewRootImpl.setView(ViewRootImpl.java:548)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:406)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:320)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:152)
at android.view.Window$LocalWindowManager.addView(Window.java:557)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2897)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$600(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4977)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.TransactionTooLargeException
at android.os.BinderProxy.transact(Native Method)
at android.view.IWindowSession$Stub$Proxy.add(IWindowSession.java:569)
at android.view.ViewRootImpl.setView(ViewRootImpl.java:538)
... 16 more
android.os.TransactionTooLargeException
at android.os.BinderProxy.transact(Native Method)
at android.view.IWindowSession$Stub$Proxy.add(IWindowSession.java:569)
at android.view.ViewRootImpl.setView(ViewRootImpl.java:538)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:406)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:320)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:152)
at android.view.Window$LocalWindowManager.addView(Window.java:557)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2897)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$600(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4977)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
It seems to be related with views, because all the Window / View lines? How is this related to remote procedure call? How can I look for the reason of this error?
In the app I'm using only Webservices, I'm not using Service class, are the Webservices the "remote procedure calls" or what else could be...?
P.S. Maybe it's important: Android version: 4.0.3, Device: HTC One X
As Intents, Content Providers, Messenger, all system services like Telephone, Vibrator etc. utilize IPC infrastructure provider by Binder.Moreover the activity lifecycle callbacks also use this infrastructure.
1MB is the overall limit on all the binder transactions executed in the system at a particular moment.
In case there are lot of transactions happening when the intent is sent,it may fail even though extra data is not large. http://codetheory.in/an-overview-of-android-binder-framework/
Make sure that you do not put into Intent object data of large size. In my case I was adding String 500k size and then starting another activity. It always failed with this exception. I avoided sharing data between activities by using static variables of activities - you don't have to send them to Intent and then pulling from it.
What I had:
This one line of code in writeToParcel(Parcel dest, int flags) method helped me to get rid of TransactionTooLargeException.
After this code only i am writing all data to the parcel object i.e dest.writeInt() etc.
This is not a definitive answer, but it may shed some light on the causes of a
TransactionTooLargeException
and help pinpoint the problem.Although most answers refer to large amounts of data transferred, I see this exception being thrown incidentally after heavy scrolling and zooming and repeatedly opening an ActionBar spinner menu. The crash happens on tapping the action bar. (this is a custom mapping app)
The only data being passed around seem to be touches from the "Input Dispatcher" to the app. I think this cannot reasonably amount to anywhere near 1 mb in the "Transaction Buffer".
My app is running on a quad core 1.6 GHz device and uses 3 threads for heavylifting, keeping one core free for the UI thread. Furthermore, the app uses android:largeHeap, has 10 mb of unused heap left and has 100 mb of room left to grow the heap. So I wouldn't say it is a resource issue.
The crash is always immediately preceded by these lines:
Which are not neccesarily printed in that order, but (as far as I checked) happen on the same millisecond.
And the stack trace itself, for clarity, is the same as in the question:
Delving into the source code of android one finds these lines:
frameworks/base/core/jni/android_util_Binder.cpp:
To me it sounds like I'm possibly hitting this undocumented feature, where the transaction fails for other reasons than a Transaction being TooLarge. They should have named it
TransactionTooLargeOrAnotherReasonException
.At this time I did not solve the issue, but if I find something useful I will update this answer.
update: it turned out my code leaked some file descriptors, the number of which is maximized in linux (typically 1024), and this seems to have triggered the exception. So it was a resource issue after all. I verified this by opening
/dev/zero
1024 times, which resulted in all kinds of weird exceptions in UI related actions, including the exception above, and even some SIGSEGV's. Apparently failure to open a file/socket is not something which is handled/reported very cleanly throughout Android.I got a TransactionTooLargeException from a Stackoverflow error in a Android Espresso test. I found the stackoverflow error stack trace in the logs when I took off the Logcat filter for my app.
I'm guessing that Espresso caused the TransactionTooLargeException when trying to handle a really large exception stacktrace.
When I am dealing with the
WebView
in my app it happens. I think it's related toaddView
and UI resources. In my app I add some code inWebViewActivity
like this below then it runs ok: