我得到了一个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


当前回答

问题通过以下方式解决:

 Bundle bundle = new Bundle();
  bundle.putSerializable("data", bigdata);
...
  CacheHelper.saveState(bundle,"DATA");
  Intent intent = new Intent(mActivity, AActivity.class);
  startActivity(intent, bb);// do not put data to intent.

In Activity:
   @Override
   protected void onCreate(Bundle savedInstanceState) {
        Bundle bundle = CacheHelper.getInstance().loadState(Constants.DATA);
        if (bundle != null){
            Intent intent = getIntent();
            intent.putExtras(bundle);
        }
        getIntent().getExtra(..);
        ....
   }
   @Override
    protected void onDestroy() {
        super.onDestroy();
        CacheHelper.clearState("DATA");
    }

public class CacheHelper {

    public static void saveState(Bundle savedInstanceState, String name) {
        Bundle saved = (Bundle) savedInstanceState.clone();
        save(name, saved);
    }
    public Bundle loadState(String name) {

        Object object = load(name);
        if (object != null) {
            Bundle bundle = (Bundle) object;
            return bundle;
        }
        return null;
    }
    private static void save(String fileName, Bundle object) {
        try {
            String path = StorageUtils.getFullPath(fileName);
            File file = new File(path);
            if (file.exists()) {
                file.delete();
            }
            FileOutputStream fos = new FileOutputStream(path, false);

            Parcel p = Parcel.obtain(); //creating empty parcel object
            object.writeToParcel(p, 0); //saving bundle as parcel
            //parcel.writeBundle(bundle);
            fos.write(p.marshall()); //writing parcel to file

            fos.flush();
            fos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static Bundle load(String fileName) {
        try {
            String path = StorageUtils.getFullPath(fileName);
            FileInputStream fis = new FileInputStream(path);

            byte[] array = new byte[(int) fis.getChannel().size()];
            fis.read(array, 0, array.length);

            Parcel parcel = Parcel.obtain(); //creating empty parcel object
            parcel.unmarshall(array, 0, array.length);
            parcel.setDataPosition(0);
            Bundle out = parcel.readBundle();
            out.putAll(out);

            fis.close();
            parcel.recycle();
            return out;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
public static void clearState(Activity ac) {
    String name = ac.getClass().getName();
    String path = StorageUtils.getFullPath(name);
    File file = new File(path);
    if (file.exists()) {
        file.delete();
    }
}
}

其他回答

我最近也遇到了这个问题,在阅读了这个和其他网站上的所有解决方案2天后,我想分享我的问题的原因和我是如何解决的,因为我没有看到我的问题。

我使用的片段是:

FragmentA ->包含一个位图回收视图 FragmentB ->启动相机并将图像捕获返回到Fragment A

FragmentB有相机的东西,所以我发送位图FragmentA使用previousBackStackEntry像这样:

findNavController().run {
    previousBackStackEntry?.savedStateHandle?.set(KEY_REPORT_PHOTO, photo)
    popBackStack()
}

最后,我在FragmentA上使用位图:

findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<Bitmap>(KEY_REPORT_PHOTO)
    ?.observe(viewLifecycleOwner) {
        it?.let { photo ->
            viewModel.addPhoto(photo)
            findNavController().currentBackStackEntry?.savedStateHandle?.set(KEY_REPORT_PHOTO, null)
        }
    }

阅读本页上的信息,我的第一种方法是找出onSaveInstanceState中发生了什么,并尝试删除回收器视图中的位图,我认为当我关闭应用程序并将其放在后台时正在保存。

最后,我意识到问题是我在导航组件的BackStackEntry中添加的位图,解决方案就像在FragmentA中使用这一行的位图一样简单:

findNavController().currentBackStackEntry?.savedStateHandle?.set(KEY_REPORT_PHOTO, null)

这个问题没有一个特定的原因。对我来说,在我的Fragment课上我是这样做的:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);
    View rootView = inflater.inflate(R.layout.snacks_layout, container); //<-- notice the absence of the false argument
    return rootView;
}

而不是这样:

View rootView = inflater.inflate(R.layout.softs_layout, container, false);

作为意图,内容提供者,信使,所有系统服务,如电话,振动器等都使用Binder提供的IPC基础设施。此外,活动生命周期回调也使用这个基础结构。

1MB是系统在特定时刻执行的所有绑定器事务的总限制。

如果在发送意图时有很多事务发生,即使额外的数据并不大,它也可能会失败。http://codetheory.in/an-overview-of-android-binder-framework/

如果你使用导航组件的ViewPager2 FragmentStateAdapter:

我在onViewCreated()中创建适配器,但每次导航回来时都会重新创建视图。由于某种原因,旧的适配器没有正确地分离并增加包的大小,直到错误发生。 我用TooLargeTool调试它,解决方案是避免在onViewCreated()中重新创建适配器。

在我的片段中,我有适配器变量:

var pagerAdapter:HomePagerAdapter?=null

在onViewCreated方法中,我只创建了一次适配器:

if(pagerAdapter == null){
  pagerAdapter = HomePagerAdapter(childFragmentManager, lifecycle, myContent)
}

为了防止IllegalArgumentException,我手动从onDestroyView中的分页器中分离适配器:

override fun onDestroyView() {
   pager.adapter = null
   super.onDestroyView()
}

在我的情况下,我得到TransactionTooLargeException作为二次崩溃后本机库崩溃与SIGSEGV。本机库崩溃没有报告,所以我只收到TransactionTooLargeException。