扩展Intent类...收到ClassCastException

时间:2010-12-28 17:11:08

标签: android

我正在尝试创建一个增强的Intent类(我将其称为DataIntent),使其能够保存Object类型的“有效负载”(而不是使用它的内置工具{ {1}}的)。 Uri扩展了Android的DataIntent类。

我的Intent创建扩展对象没有任何问题,Activity的调用也没有任何问题。但是,在我回复startActivityForResult()时,当我调用Activity方法并尝试将其投放到我的getIntent()时,我会抛出DataIntent

我意识到这可能是一个非常愚蠢的问题 - 提前预测了1000个 - 但是有人知道为什么我不能将它投射到ClassCastException,因为那是用于启动新DataIntent的内容, ActivityDataIntent的孩子?

Intent

3 个答案:

答案 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继承了意向附加项。

现在,您有一个包装得很好的类,谁来负责定义活动的合同并向活动提供合同数据。

如果您是该项目的新工程师,那么您将不会误解如何使用它。没有文档可供阅读。