我正在尝试创建一个增强的Intent
类(我将其称为DataIntent
),使其能够保存Object类型的“有效负载”(而不是使用它的内置工具{ {1}}的)。 Uri
扩展了Android的DataIntent
类。
我的Intent
创建扩展对象没有任何问题,Activity
的调用也没有任何问题。但是,在我回复startActivityForResult()
时,当我调用Activity
方法并尝试将其投放到我的getIntent()
时,我会抛出DataIntent
。
我意识到这可能是一个非常愚蠢的问题 - 提前预测了1000个 - 但是有人知道为什么我不能将它投射到ClassCastException
,因为那是用于启动新DataIntent
的内容, Activity
是DataIntent
的孩子?
Intent
答案 0 :(得分:4)
抱歉,你不能这样做。您需要将数据放在Intent中。 Intent对象在进程之间移动,因此您获取的对象与您创建的实例不同。
答案 1 :(得分:1)
我做了同样的事情CirrusFlyer。在我开始实现之前,我还查找了final关键字。 Google应该将Intent类标记为最终版。
答案 2 :(得分:1)
您可以并且应该扩展Intent,但是您必须了解Intent的目的。
#1 意图必须是可拆分的,以支持在应用程序重新启动期间持久保留意图数据(由于内存限制,trimMemory等原因而崩溃)。
#2 了解调用者构造的Intent不是提供给活动的Intent。这是由于项目#1。因此,所有对象引用都将丢失,这是一个坏主意-必须牢记于心。
#3 意图仅应包含活动(或任何其他内容)的数据上下文。因此,您不应将数据页面放入意图中,而应包含ID或键,或者为重新获取活动数据所需的任何上下文数据(或其他内容)。
现在...为什么要扩展Intent?为了获得好的合同!
意图本身就是可怕的合同,太松散了。有些人创建了静态方法助手,但是有更好的方法。
如果ABCActivity要求“ A”,“ B”和“ C”正常运行。通用意图无法描述这一点,我们将依靠没有人会阅读的文档。
相反,我们可以创建一个构造函数需要A,B和C的ABCIntent。这将为加载活动所需的内容创建清晰的合同。我们可以使用静态方法来做到这一点,但是ABCIntent还可以为A B C提供吸气剂,从而使其成为一个干净的打包合同,用于描述加载活动的要求以及如何获取数据。
有一个警告,我们需要一个私有的构造函数来从继承附加对象的通用意图构造ABCIntent。
public ABCActivity extends Activity {
private ABCIntent intent;
public static ABCIntent extends Intent {
private ABCIntent(Intent intent) {
super(intent);
}
public ABCIntent(A a, B b, C c) {
putExtra("EXTRA_A", A.serialize(a));
putExtra("EXTRA_B", B.serialize(b));
putExtra("EXTRA_C", C.serialize(c));
}
public A getA() { return A.deserialize(getExtra("EXTRA_A")); }
public B getB() { return B.deserialize(getExtra("EXTRB_B")); }
public C getC() { return C.deserialize(getExtra("EXTRC_C")); }
}
@Override
protected ABCIntent getIntent() {
return intent == null ? (intent = new ABCIntent(super.getIntent())) : intent;
}
@Override
protected void onCreate( ... ) {
A a = getIntent().getA();
B b = getIntent().getB();
C c = getIntent().getC();
// TODO: re-obtain activity state based on A, B, C then render
}
}
请注意,我们是根据意图构造ABCIntent的。 ABCIntent继承了意向附加项。
现在,您有一个包装得很好的类,谁来负责定义活动的合同并向活动提供合同数据。
如果您是该项目的新工程师,那么您将不会误解如何使用它。没有文档可供阅读。