Intent.putExtras 大小有限制吗?
我试图通过 Intent.putExtras
将数据从一个活动传递到另一个活动,如下所示:
private ArrayList<HashMap<String, String>> mGroups = new ArrayList<HashMap<String, String>>();
private ArrayList<HashMap<String, String>> mUsers = new ArrayList<HashMap<String, String>>();
...
Bundle data = new Bundle();
data.putInt("mode", mode);
data.putSerializable("groups", (Serializable) mGroups);
data.putSerializable("users", (Serializable) mUsers);
data.putInt("current_class", mCurrentClassId);
data.putInt("current_user", mCurrentUserId);
Intent intent = new Intent(ctx, ChildActivity.class);
intent.putExtras(data);
ctx.startActivityForResult(intent, 0);
这里 mUsers
是 HashMap
的列表code> 包含用户数据,包括 Base64 编码的照片,此列表中的字符串大小总和约为 500Kb
对 startActivityForResult
的调用在黑屏下挂起几分钟,然后我得到ANR 错误。子Activity的onCreate
根本没有被调用。
如果我不将大字符串添加到 mUsers 中(没有 Base64 编码的照片) - 工作得很好。
请帮忙。
I'm trying to pass data from one activity to another via Intent.putExtras
like this:
private ArrayList<HashMap<String, String>> mGroups = new ArrayList<HashMap<String, String>>();
private ArrayList<HashMap<String, String>> mUsers = new ArrayList<HashMap<String, String>>();
...
Bundle data = new Bundle();
data.putInt("mode", mode);
data.putSerializable("groups", (Serializable) mGroups);
data.putSerializable("users", (Serializable) mUsers);
data.putInt("current_class", mCurrentClassId);
data.putInt("current_user", mCurrentUserId);
Intent intent = new Intent(ctx, ChildActivity.class);
intent.putExtras(data);
ctx.startActivityForResult(intent, 0);
Here mUsers
is a List of HashMap<String,String>
with users' data, including Base64-encoded photo, sum of strings sizes in this list is about 500Kb
Call to startActivityForResult
hangs for several minutes with black screen and then I get ANR error. Sub-Activity's onCreate
is not called at all.
If I don't add large strings into mUsers (no Base64-encoded photos) - works just fine.
Please help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果这两项活动都是您的,请使用合适的数据模型。 Android 并不鼓励设计精良的应用程序。或者换个角度来看,它允许快速开发应用程序,并且不会促进太多良好的软件应用程序原则。
@Jean-Philippe Roy(魁北克?)的解决方案很有趣,但当涉及到更复杂的事物(即有状态模型或 serviceS)时,单例是一种相当反模式。
最好的选择是使用应用程序类。这个类本质上是 Android 中的单例。因此,
---在 @straya 的回答和 18 个多月的 Android 编程之后更新:)
共享的问题在构建 Android 应用程序时,始终会考虑跨应用程序、活动、视图、片段的数据结构或流程。重要的是要了解并考虑应用程序范围是保存共享结构的正确位置,但是使用应用程序类本身将数据结构放入该范围内是不可行的:
我现在倾向于使用依赖注入管理的单例。 Dagger 或 RoboGuice 都允许创建给定类的单个实例并将其注入到其他类中。这种技术以及更普遍的 DI 为良好的 Android 设计提供了巨大的可能性:
if both activities are yours, use a decent data model. Android doesn't encourage that much to very well designed application. Or turn it differently, it allows for fast developped application and doesn't promote much of good software application principle.
The solution of @Jean-Philippe Roy (québec ?) is interesting but singleton are quite an anti-pattern when it comes to more elaborate things, namely statefull models or serviceS.
The best option is to use an application class. This class is your singleton, by nature in android. So,
---Updated after @straya's answer and 18 more month of Android programming :)
The question of sharing a data structure or processes accross application, activities, views, fragments is always present at mind when building Android application. It's important to know and consider that the application scope is the right place to hold shared structure, but using the application class itself to put a data structure in that scope is not viable with regards to :
I now tend to prefer using Dependency Injection managed singletons. Dagger or RoboGuice both allow to create and inject a single instance of a given class into other classes. This technique, and DI more generally offers great possibilities for good Android designs :
在进程级别,最大大小为1MB,而不是在捆绑包级别。这 1MB 用于应用程序进程中正在进行的所有状态事务(例如 onSaveInstanceState、startActivity 等)使用的共享缓冲区。
在 Android 7.0(API 级别 24)及更高版本上,当达到此进程级别限制时,系统会抛出 TransactionTooLargeException。在旧版本上,您只会收到警告。
正如其他人所建议的,如果您需要传递更大的有效负载,您应该研究替代方案,例如使用本地数据库、文件系统、应用程序级内存缓存、远程存储、共享首选项(尽管这些也需要很小)等。
事实来源: https://developer.android.com/guide/components/activities/parcelables-and-bundles
Maximum size is 1MB at Process Level, not at bundle level. This 1MB is for a shared buffer used by all state transactions in progress in the app's process, e.g. onSaveInstanceState, startActivity and others.
On Android 7.0 (API level 24) and higher, the system throws a TransactionTooLargeException when this process level limit is reached. On older versions you only get a warning.
As others suggested, you should research alternatives, if you need to pass a larger payload, e.g. use local database, file system, application level in-memory cache, remote storage, shared preferences (although these need to be small too), etc.
Source of truth: https://developer.android.com/guide/components/activities/parcelables-and-bundles
只是为了回应 Snicolas 的回答:
应用程序已经是单例,无需将其“变成”单例。
就我个人而言,在长期严重依赖应用程序来保存数据之后,我开始不再完全信任它。不过,我使用自缓存数据对象来缓解问题;)
Just in response to Snicolas' answer:
Application is already a Singleton, no need to "turn it to" one.
Personally, after some serious reliance on Application to hold data for a long time, I've come to not trust it entirely. I use self-caching data objects to mitigate the problems though ;)