我得到了一个TransactionTooLargeException。无法复制的。文件里说

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). ...

在某个地方,我传递或接收的参数超出了未知的限制。在哪里?

stacktrace没有显示任何有用的东西:

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)

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

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


当前回答

另一个可能的原因是:

我有一个活动,开始自己在onResume()!这会导致大量的事务,导致手机(Galaxy S2)完全冻结(没有ANR或任何东西),然后硬重置,这本身就是一个巨大的错误。

看看在其他手机上用这个代码会发生什么会很有趣:

class MyActivity extends Activity
{
  // ...
  @Override
  void onResume()
  {
     super.onResume()
     startActivity(new Intent(this, MyActivity.class));
  }
}

我不是说你应该使用那个代码。

其他回答

我在卸载另一个应用程序正在进行IPC调用的应用程序时得到了这个错误。

一个假设是;由于“服务”应用程序因为卸载而消失,一些传输缓冲区可能已经被填满,导致这个错误,因为没有东西不再从缓冲区中“弹出东西”。

如果这是你的情况,这个问题可能没什么好担心的。

我遇到了相同的问题与ViewPager2和FragmentStateAdapter这里的问题是FragmentStateAdapter标记'saveState()'作为最终和ViewPager2类也是最终的,所以我们不能覆盖的方法,建议在其他答案使现有的答案不适用。

在我的情况下,我能够摆脱事务太大的问题,不保存分页器的状态添加\android:saveEnabled="false" '在XML条目的视图分页器

<androidx.viewpager2.widget.ViewPager2
    android:saveEnabled="false"
    android:id="@+id/viewPager"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

TransactionTooLargeException已经困扰我们大约4个月了,我们终于解决了这个问题!

发生的是我们在ViewPager中使用FragmentStatePagerAdapter。用户将翻页并创建100多个片段(这是一个阅读应用程序)。

虽然我们在destroyItem()中正确地管理片段,但在android中 FragmentStatePagerAdapter的实现有一个bug,它保持了对以下列表的引用:

private ArrayList<Fragment.SavedState> mSavedState = new ArrayList<Fragment.SavedState>();

当Android的FragmentStatePagerAdapter尝试保存状态时,它将调用该函数

@Override
public Parcelable saveState() {
    Bundle state = null;
    if (mSavedState.size() > 0) {
        state = new Bundle();
        Fragment.SavedState[] fss = new Fragment.SavedState[mSavedState.size()];
        mSavedState.toArray(fss);
        state.putParcelableArray("states", fss);
    }
    for (int i=0; i<mFragments.size(); i++) {
        Fragment f = mFragments.get(i);
        if (f != null && f.isAdded()) {
            if (state == null) {
                state = new Bundle();
            }
            String key = "f" + i;
            mFragmentManager.putFragment(state, key, f);
        }
    }
    return state;
}

正如您所看到的,即使您正确地管理FragmentStatePagerAdapter子类中的片段,基类仍然会存储一个片段。SavedState用于创建的每个片段。TransactionTooLargeException会在数组被转储到parcelableArray时发生,而操作系统不希望它有100+项。

因此,我们的解决方案是重写saveState()方法,不为“状态”存储任何东西。

@Override
public Parcelable saveState() {
    Bundle bundle = (Bundle) super.saveState();
    bundle.putParcelableArray("states", null); // Never maintain any states from the base class, just null it out
    return bundle;
}

重要的是要理解,无论设备功能或应用程序,事务缓冲区被限制为1mb。这个缓冲区用于你所做的每个API调用,并在应用程序当前运行的所有事务之间共享。

我相信它还包含一些特定的对象,如包裹和such (package . get()),因此始终将每个get()与recycle()匹配是很重要的。

这个错误很容易发生在返回大量数据的API调用上,即使返回的数据小于1 MB(如果其他事务仍在运行)。

例如,PackageManager.getInstalledApplication()调用返回已安装的所有应用程序的列表。添加特定的标志可以检索大量额外的数据。这样做很可能会失败,所以建议不要检索任何额外的数据,并在每个应用程序的基础上检索这些数据。

然而,调用仍然可能失败,因此重要的是用一个捕获来包围它,并在必要时能够重试。

据我所知,除了重新尝试并确保检索尽可能少的信息之外,没有解决这个问题的方法。

当我试图通过Intent发送位图时,我也遇到了同样的问题,同时当它发生时,我折叠了应用程序。

当Activity处于停止的过程中,这意味着Activity试图将其保存的状态Bundles发送到系统操作系统,以便以后(在配置更改或进程死亡之后)安全恢复,但它发送的一个或多个Bundles太大了。

我通过重写onSaveInstanceState在我的活动中解决了这个问题:

@Override
protected void onSaveInstanceState(Bundle outState) {
    // super.onSaveInstanceState(outState);
}

注释调用super。这是一个肮脏的hack,但它是完美的工作。位图成功发送,没有崩溃。 希望这能帮助到一些人。