[关闭]
@ZeroGeek 2017-06-27T06:30:36.000000Z 字数 3366 阅读 1600

Activity之间使用intent传递大量数据问题

bug


问题:设 A -> B ,当传递数据量过大,会导致B无法启动。现象即启动失败,activityB的oncreate()都不会执行。

会提示 TransactionTooLargeException 异常

TransactionTooLargeException 官网解释

  1. The Binder transaction failed because it was too large.
  2. 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.
  3. The Binder transaction buffer has a limited fixed size, currently 1Mb, which is shared by all transactions in progress for the process. Consequently this exception can be thrown when there are many transactions in progress even when most of the individual transactions are of moderate size.
  4. // 一般进程中有 1MB Binder transaction buffer 共享传递的数据,大小超过这个buffer,则会抛出该异常。
  5. 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). It is not possible to tell which of these outcomes actually occurred. The client should assume that a partial failure occurred.
  6. // 这段话可以 结合使用AIDL或Messenger的场景来理解(因为都是通过Binder对象传值)
  7. // 2种可能结果
  8. //1:客户端传递的数据大于the transaction buffer
  9. //2:服务端返回的数据大于the transaction buffer
  10. The key to avoiding TransactionTooLargeException is to keep all transactions relatively small. Try to minimize the amount of memory needed to create a Parcel for the arguments and the return value of the remote procedure call. Avoid transferring huge arrays of strings or large bitmaps. If possible, try to break up big requests into smaller pieces.
  11. // 避免的建议: 保证所有传递数据尽量小
  12. // 1. 使用 Parcel
  13. // 2. 避免传递大数组,字符串集,位图
  14. // 3. 大请求压缩为更小块
  15. If you are implementing a service, it may help to impose size or complexity contraints on the queries that clients can perform. For example, if the result set could become large, then don't allow the client to request more than a few records at a time. Alternately, instead of returning all of the available data all at once, return the essential information first and make the client ask for additional information later as needed.
  16. // 实现service的建议

Binder (引自Android开发艺术探索)

解决思路:

处理例子:

1.
when i am dealing with the WebViewin my app,it happens.i think it's related to 'addView' and UI resources. in my app ,i add some code in WebViewActivity like this below,it runs ok:

  1. @Override
  2. protected void onDestroy() {
  3. if (mWebView != null) {
  4. ((ViewGroup) mWebView.getParent()).removeView(mWebView);
  5. mWebView.removeAllViews();
  6. mWebView.destroy();
  7. }
  8. super.onDestroy();
  9. }

2.
There isn't one specific cause of this problem.For me, in my Fragment class I was doing this:

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

instead of this:

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

http://www.tuicool.com/articles/QBBvy22
http://stackoverflow.com/questions/11451393/what-to-do-on-transactiontoolargeexception
http://androiddoc.qiniudn.com/reference/android/os/TransactionTooLargeException.html

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注