如何处理TransactionTooLargeException

如何处理TransactionTooLargeException

我有一个TransactionTooLargeException..不能重复。在文档里写着

Binder事务失败,因为它太大了。

在远程过程调用期间,参数和调用的返回值作为存储在Binder事务缓冲区中的Packcel对象传输。如果参数或返回值太大,无法适应事务缓冲区,那么调用将失败,TransactionTooLargeException将被抛出。

...

当远程过程调用抛出TransactionTooLargeException时,有两种可能的结果。客户端无法将其请求发送到服务(最可能的情况是参数太大,无法适应事务缓冲区),或者服务无法将其响应发送回客户端(最可能的情况是返回值太大,无法适应事务缓冲区)。

...

所以在某个地方,我正在传递或接收一些超越未知极限的论点。哪里?

堆栈跟踪没有显示任何有用的内容:

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)

它似乎与观点有关?这与远程过程调用有什么关系?

可能很重要:Android版本:4.0.3,设备:HTC One X


茅侃侃
浏览 1475回答 3
3回答

UYOU

我遇到了这个问题,我发现当服务和应用程序之间交换了大量数据时(这涉及到传输大量缩略图)。实际上,数据大小约为500 kb,IPC事务缓冲区大小设置为1024 KB。我不知道为什么它超过了事务缓冲区。当您通过意图附加传递大量数据时,也会发生这种情况。当您在应用程序中获得此异常时,请分析您的代码。您是否在服务和应用程序之间交换大量数据?使用意图共享大量数据(例如,用户从图片库共享中选择大量文件,所选文件的URI将使用intents传输)从服务接收位图文件等待Android用大量数据进行响应(例如,当用户安装大量应用程序时,getInstalledApplications()将applyBatch()与许多未完成的操作一起使用当您得到此异常时,如何处理?如果可能的话,将大操作分割成小块,例如,不要用1000个操作调用applyBatch(),而要调用每个操作100个。不要在服务和应用程序之间交换大量数据(>1MB)。我不知道怎么做,但是不要查询Android,它可以返回巨大的数据:-)

慕码人2483693

这并不是一个明确的答案,但它可能会揭示一些原因。TransactionTooLargeException帮助找出问题所在。尽管大多数答案都涉及到传输的大量数据,但我看到这个异常是在大量滚动和缩放并反复打开ActionBar旋转菜单之后抛出的。碰撞发生在敲击动作杆上。(这是一个自定义映射应用程序)唯一传递的数据似乎是从“输入分配器”到应用程序的接触。我认为这不能合理地相当于“事务缓冲区”中接近1MB的任何东西。我的应用程序运行在一个1.6GHz的四核设备上,使用3个线程进行重举,为UI线程保留一个内核。此外,该应用程序使用Android:LargeHeap,还剩下10 MB未使用的堆,还有100 MB的空间用于堆的增长。所以我不会说这是资源问题。坠机前总是有以下几行:W/InputDispatcher( 2271): channel ~ Consumer closed input channel or an error occurred.  events=0x9E/InputDispatcher( 2271): channel ~ Channel is unrecoverably broken and will be disposed!E/JavaBinder(28182): !!! FAILED BINDER TRANSACTION !!!它们不是按这个顺序印刷的,但(据我所查)发生在同一毫秒内。为了清晰起见,堆栈跟踪本身与问题相同:E/AndroidRuntime(28182): java.lang.RuntimeException: Adding window failed..E/AndroidRuntime(28182): Caused by: android.os.TransactionTooLargeException深入研究AndroidOne的源代码,可以发现以下几行:frameworks/base/core/jni/android_util_Binder.cpp:case FAILED_TRANSACTION:     ALOGE("!!! FAILED BINDER TRANSACTION !!!");     // TransactionTooLargeException is a checked exception, only throw from certain methods.     // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION     //        but it is not the only one.  The Binder driver can return BR_FAILED_REPLY     //        for other reasons also, such as if the transaction is malformed or     //        refers to an FD that has been closed.  We should change the driver     //        to enable us to distinguish these cases in the future.     jniThrowException(env, canThrowRemoteException            ? "android/os/TransactionTooLargeException"                     : "java/lang/RuntimeException", NULL);在我看来,这听起来像是我碰到了这个没有文档的特性,在这里,事务失败了,而不是因为一个交易是TooLarge。他们应该给它起个名字TransactionTooLargeOrAnotherReasonException.此时我没有解决这个问题,但是如果我找到有用的东西,我会更新这个答案。最新情况:结果,我的代码泄露了一些文件描述符,在Linux(通常是1024)中,文件描述符的数量最大,这似乎触发了异常。所以这毕竟是一个资源问题。我通过打开/dev/zero1024次,导致UI相关操作出现各种奇怪的异常,包括上述异常,甚至一些SIGSEGV。显然,在整个Android系统中,未能打开文件/套接字并不是非常干净的处理/报告。

白衣非少年

这个TransactionTooLargeException已经困扰我们四个月了,我们终于解决了这个问题!发生的事情是我们用的是FragmentStatePagerAdapter在.ViewPager..用户将分页浏览并创建100+片段(它是一个读取应用程序)。虽然我们在destroyItem(),在仙女座FragmentStatePagerAdapter有一个bug,它保存了对以下列表的引用:private&nbsp;ArrayList<Fragment.SavedState>&nbsp;mSavedState&nbsp;=&nbsp;new&nbsp;ArrayList<Fragment.SavedState>();当安卓系统FragmentStatePagerAdapter尝试保存状态,它将调用该函数。@Overridepublic&nbsp;Parcelable&nbsp;saveState()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;Bundle&nbsp;state&nbsp;=&nbsp;null; &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(mSavedState.size()&nbsp;>&nbsp;0)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state&nbsp;=&nbsp;new&nbsp;Bundle(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fragment.SavedState[]&nbsp;fss&nbsp;=&nbsp;new&nbsp;Fragment.SavedState[mSavedState.size()]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mSavedState.toArray(fss); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state.putParcelableArray("states",&nbsp;fss); &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i=0;&nbsp;i<mFragments.size();&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Fragment&nbsp;f&nbsp;=&nbsp;mFragments.get(i); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(f&nbsp;!=&nbsp;null&nbsp;&&&nbsp;f.isAdded())&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(state&nbsp;==&nbsp;null)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state&nbsp;=&nbsp;new&nbsp;Bundle(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;key&nbsp;=&nbsp;"f"&nbsp;+&nbsp;i; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mFragmentManager.putFragment(state,&nbsp;key,&nbsp;f); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;state;}如您所见,即使您正确地管理FragmentStatePagerAdapter类,则基类仍将存储Fragment.SavedState为每一个曾经创造的片段。这个TransactionTooLargeException当该数组转储到parcelableArray而且操作系统也不喜欢它的100多个项目。因此,我们的修复方法是覆盖saveState()方法和不储存任何东西"states".@Overridepublic&nbsp;Parcelable&nbsp;saveState()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;Bundle&nbsp;bundle&nbsp;=&nbsp;(Bundle)&nbsp;super.saveState(); &nbsp;&nbsp;&nbsp;&nbsp;bundle.putParcelableArray("states",&nbsp;null);&nbsp;//&nbsp;Never&nbsp;maintain&nbsp;any&nbsp;states&nbsp;from&nbsp;the&nbsp;base&nbsp;class,&nbsp;just&nbsp;null&nbsp;it&nbsp;out &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;bundle;}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Android