启动新Activity时的TransactionTooLargeException

时间:2013-02-15 15:19:41

标签: android android-intent binding

我认为Intent的额外限制大小为1MB,如docs所述。无论如何,我失去了一天追逐这个可怕的TransactionTooLargeException

 E/JavaBinder(368): !!! FAILED BINDER TRANSACTION !!!
 Exception when starting activity android/com.android.internal.app.ChooserActivity
 android.os.TransactionTooLargeException
at android.os.BinderProxy.transact(Native Method)
at    android.app.ApplicationThreadProxy.scheduleLaunchActivity(ApplicationThreadNative.java:705)
at com.android.server.am.ActivityStack.realStartActivityLocked(ActivityStack.java:690)
at com.android.server.am.ActivityStack.startSpecificActivityLocked(ActivityStack.java:799)
at com.android.server.am.ActivityStack.resumeTopActivityLocked(ActivityStack.java:1743)
at com.android.server.am.ActivityStack.resumeTopActivityLocked(ActivityStack.java:1381)
at com.android.server.am.ActivityStack.completePauseLocked(ActivityStack.java:1129)
at com.android.server.am.ActivityStack.activityPaused(ActivityStack.java:1027)
at com.android.server.am.ActivityManagerService.activityPaused(ActivityManagerService.java:4288)
at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:381)
at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:1611)
at android.os.Binder.execTransact(Binder.java:367)
at dalvik.system.NativeStart.run(Native Method)

糟糕的是startActivity失败了,但是ActivityManager不断重复它,产生无限的进程。这似乎在this博客文章中得到了确认,其中作者指出'限制'为86389个字符。我的相关代码很简单:

                    Intent myIntent = new Intent(activity, VacancySwipeActivity.class);
                    //myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                    Bundle ex = new Bundle();
                    ex.putSerializable(Constants.Extra.VACANCY, vacancies);
                    ex.putString("token", token);
                    ex.putString("cosa", cosa.getText().toString());

                    ex.putInt("dist", searchDistance.getProgress());
                    ex.putString("dove", dove.getText().toString());
                    if (ret.getSearchLocation() != null) {
                        ex.putParcelable("userLoc", ret.getSearchLocation());
                    }
                    ex.putInt("totRows", ret.getTotFound());

                    myIntent.putExtras(ex);
                    activity.startActivity(myIntent);

ArrayList空缺非常小,大约8个POJO,它被加载到一个线程中,然后通过Intent的额外传递给一个新的活动。如果我将它增加到大约90k,应用程序无限循环需要重新启动,这是一个真正的烦恼。 其他人经历过这个

2 个答案:

答案 0 :(得分:1)

我有同样的问题,通过制作单例Hashtable来解决它,我保存了我的“长”字符串,并且我只给出了意图中的键。

答案 1 :(得分:1)

限制应该是1MB,但它因设备而异,从不到512KB到几乎完整的1MB。除此之外,你还有另一个问题。你将ArrayList作为额外的东西,因为ArrayList实现了Serializable,所以这很好。但是如果你认为android会将这个列表序列化为byte []并转移你错了。它将自己序列化每个项目并传输它。这比听起来效率低得多。您应该将ArrayList包装在一个实现Serializable的包装器对象中,这将产生巨大的差异。有关详细信息,请参阅此blog post(我的)。