Intent extra 因未知原因被清除
Intent extra gets cleared out from unknown reason
我有 Activity A 以 Activity B 开头,代码如下:
Intent intent = new Intent(this, B.class);
intent.putExtra("foo", new MySerializableObject());
startActivity(intent);
In B "foo" 被正确接收,然后我创建 PendingIntent 以在一段时间后自行启动,您可以将其视为一些闹钟应用程序。无论如何,神秘的是当我按照以下方式安排这个意图时:
Intent intent = new Intent(context, B.class);
intent.putExtra("bar", true);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + delayMs, pendingIntent);
然后一切都很好(收到此意图后 "bar" 值为真),但是如果我在 "bar" 之前或之后添加以下行:
intent.putExtra("foo", new MySerializableObject());
然后当我收到此意图时,"foo" 和 "bar" 都丢失了。我的意思是 false 从这两行返回:
getIntent().hasExtra("foo")
getIntent().hasExtra("bar")
这种行为的原因可能是什么?
编辑:
根据我尝试过的评论中的建议:
intent.putExtra("foo", true);
intent.putExtra("bar", true);
它起作用了,所以我认为 MySerializableObject 可能有问题,所以这就是我接下来尝试的方法:
intent.putExtra("foo",
new Serializable() {
@Override
public int hashCode() { return super.hashCode(); }
});
intent.putExtra("bar", true);
但这会导致与我描述的完全相同的问题("foo" 和 "bar")丢失。最后我也尝试用 "xxx" 替换 "foo" 但它没有改变任何东西,所以对我来说它看起来像一些奇怪的 Android 错误。
根据 android-hub 的建议,我尝试使用 Bundle,但问题是一样的。这有效("bar" 可用):
Bundle b = new Bundle();
b.putBoolean("bar", true);
intent.putExtras(b);
虽然这不存在("xxx" 和 "bar" 都不存在):
Bundle b = new Bundle();
b.putSerializable("xxx", new Serializable() {});
b.putBoolean("bar", true);
intent.putExtras(b);
提到的 稍微解释了正在发生的事情,但是如您所见,建议的解决方案(使用 Bundle)不起作用。不管怎样,我猜这部分是正确的解释:
if a core OS process needs to modify the Intent extras, that process winds up trying to recreate your Serializable objects as part of setting up the extras Bundle for modification. That process does not have your class and so it gets a runtime exception.
阅读后我在日志中看到了这个:
W/Intent: Failure filling in extras java.lang.RuntimeException:
Parcelable encountered ClassNotFoundException reading a Serializable
object (name = test.edu.B)
之前我错过了,因为我只是查看我的应用程序中的日志。无论如何,我可能不得不将 MySerializableObject 分解为本机类型(字符串、int 数组等),为它们创建特殊键等,我想这会起作用但很痛苦。我不想使用 Parcelable(即使它可以工作)因为我不希望我的模型 类 是 Android 特定的。
在浪费了你我几个小时的时间来确定这个问题之后,我唯一能说的是 Google 在那个特定情况下 的设计非常糟糕 。在我看来,PendingIntent 应该检查是否将一些可序列化的内容添加到意图中,并在我的应用程序中抛出一些不受支持的异常,或者如果不能很好地处理,不应该首先将 Serializable 添加到 Intent 中 API与其他 Android 组件。
我有 Activity A 以 Activity B 开头,代码如下:
Intent intent = new Intent(this, B.class);
intent.putExtra("foo", new MySerializableObject());
startActivity(intent);
In B "foo" 被正确接收,然后我创建 PendingIntent 以在一段时间后自行启动,您可以将其视为一些闹钟应用程序。无论如何,神秘的是当我按照以下方式安排这个意图时:
Intent intent = new Intent(context, B.class);
intent.putExtra("bar", true);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + delayMs, pendingIntent);
然后一切都很好(收到此意图后 "bar" 值为真),但是如果我在 "bar" 之前或之后添加以下行:
intent.putExtra("foo", new MySerializableObject());
然后当我收到此意图时,"foo" 和 "bar" 都丢失了。我的意思是 false 从这两行返回:
getIntent().hasExtra("foo")
getIntent().hasExtra("bar")
这种行为的原因可能是什么?
编辑: 根据我尝试过的评论中的建议:
intent.putExtra("foo", true);
intent.putExtra("bar", true);
它起作用了,所以我认为 MySerializableObject 可能有问题,所以这就是我接下来尝试的方法:
intent.putExtra("foo",
new Serializable() {
@Override
public int hashCode() { return super.hashCode(); }
});
intent.putExtra("bar", true);
但这会导致与我描述的完全相同的问题("foo" 和 "bar")丢失。最后我也尝试用 "xxx" 替换 "foo" 但它没有改变任何东西,所以对我来说它看起来像一些奇怪的 Android 错误。
根据 android-hub 的建议,我尝试使用 Bundle,但问题是一样的。这有效("bar" 可用):
Bundle b = new Bundle();
b.putBoolean("bar", true);
intent.putExtras(b);
虽然这不存在("xxx" 和 "bar" 都不存在):
Bundle b = new Bundle();
b.putSerializable("xxx", new Serializable() {});
b.putBoolean("bar", true);
intent.putExtras(b);
提到的
if a core OS process needs to modify the Intent extras, that process winds up trying to recreate your Serializable objects as part of setting up the extras Bundle for modification. That process does not have your class and so it gets a runtime exception.
阅读后我在日志中看到了这个:
W/Intent: Failure filling in extras java.lang.RuntimeException: Parcelable encountered ClassNotFoundException reading a Serializable object (name = test.edu.B)
之前我错过了,因为我只是查看我的应用程序中的日志。无论如何,我可能不得不将 MySerializableObject 分解为本机类型(字符串、int 数组等),为它们创建特殊键等,我想这会起作用但很痛苦。我不想使用 Parcelable(即使它可以工作)因为我不希望我的模型 类 是 Android 特定的。
在浪费了你我几个小时的时间来确定这个问题之后,我唯一能说的是 Google 在那个特定情况下 的设计非常糟糕 。在我看来,PendingIntent 应该检查是否将一些可序列化的内容添加到意图中,并在我的应用程序中抛出一些不受支持的异常,或者如果不能很好地处理,不应该首先将 Serializable 添加到 Intent 中 API与其他 Android 组件。