开发者

Extending the Intent class ... received ClassCastException

I am attemptin开发者_如何学Pythong to create an enhanced Intent class (I call it DataIntent) by giving it the ability to hold a "payload" of type Object (versus using it's built-in facility for Uri's). DataIntent extends Android's Intent class.

My Activity creates the extended object without any problems and the invocation of the startActivityForResult() goes off without any problems also. But, in my responding Activity when I call the getIntent() method, and attempt to cast it to my DataIntent, I'll throw the ClassCastException.

I realize this is probably a very dumb question - a 1,000 appologies in advance - but does anyone know why I cannot cast it to the DataIntent since that's what was used to start the new Activity, and DataIntent is a child of Intent?

DataIntent dataIntent = (DataIntent)getIntent(); 
 // invoked inside the responding Activity instance - throws a ClassCastException


You can't do that, sorry. You need to place your data inside of the Intent. The Intent object is moved across processes and thus the one you get back is not the same instance as the one you created.


I did the same thing CirrusFlyer. I also looked for the final keyword before I started to implement it. Google should mark Intent class as final.


You can and should extend an Intent, but you must understand the purpose of an Intent.

#1 an intent must be parcelable to support persisting the intent-data across an app restart (collapsed due to memory limitations, trimMemory etc).

#2 Understand that the Intent constructed by the caller, is not the Intent provided to the activity. This is due to item #1. So any object references would be lost and are a bad idea -- it needs to be parcelable remember.

#3 Intents should only contain data-context for the activity (or whatever). So you should not place pages of data into an intent, rather, it should contain ids or keys, or whatever contextual data is necessary to re-obtain the data for the activity (or whatever).

Now... Why should you extend an Intent? For good contracts!

Intents by themselves are terrible contracts, way too loose. Some people create static method helpers but there is a better way.

If an ABCActivity requires "A" "B" and "C" to perform properly. A generic intent cannot describe that, we'd rely on documentation that no one will read.

Instead we can create a ABCIntent whose constructor demands A,B & C. This creates a clear contract on what is required to load the activity. We can do that with a static method, but a an ABCIntent can also provide getters for A B C making it a clean packaged contract for describing requirements to load the activity and how to obtain the data.

There is one caveat, we need a private constructor to construct our ABCIntent from a generic intent to inherit the extras.

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
  }
}

Notice that we construct ABCIntent from intent. The ABCIntent inherits the intent extras.

Now you have a nicely packaged class who's job it is to define the contract for the activity and to provide the contractual data to the activity.

If you're a new engineer on the project, there is no way for you to misunderstand how to use this. No docs to read.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜