Android Hack – Parcellable in eclipse

Long story short – I have been playing around with android.

wow. Amazing platform. Ok so the sdk is not all that well documented but it is getting better by the day. Ofcourse due to its young age, it is nowhere near the flex sdk in terms of the ease of use, documentation and ide, but hey a great start. And there are tons of samples out there ofcourse.

Anyhoo today is about one of the many problems and a fix I stumbled across – Including Parcelables in eclipse projects.

Background:

It is very easy to create remote services in android. A remote service runs in the corner handling requests by activities (or other processes in general) that need to use them (essentially server like processes). By following the tutorial above, you will find that “aidl” files come in 2 flavours.

1. Include the interface definition of an interface.

2. Contain a single statement “parcelable xxxx”, indicating that class xxxx can be marshalled and unmarshalled (into Parcel objects) so instances of xxxx can be communicated between processes.

With step 1, an aidl file YYYYY.aidl automatically gets built into YYYYY.java which contains a lot of stub and other helper functions to take care marshalling and remote method invocation and yada yada yada. This seems to be an automatic thing with eclipse.

With step 2, the .java already exists, and hence the need to use the “parcelable” keyword to indicate that “there exists a corresponding XXXX.java that is already parcelable so do NOT create a .java file again”, but eclipse does not understand this.

Worse still, it is intuitive to place the aidl files along with all your other sources. The fix involves NOT doing this.

Your project will have usually have the following structure:

<project>

—- .classpath

—- .project

—- .settings/

—- bin/

—- src/

——– package1

————file1.java —> This is parcellable

————file2.java

——– package2

————interface1.java

————class2.java —-> This is parcellable

and so on

the key is to add another folder at the same level and structure as the “src” folder(I called mine aidl).

So the new structure looks like this:

<project>

—- .classpath

—- .project

—- .settings/

—- bin/

—- src/

——– package1

————file1.java —> This is parcellable
————file2.java

——– package2

————interface1.java

————class2.java —-> This is parcellable

—- aidl/

——– package1

————file1.aidl —> This is parcellable
——– package2

———— class1.aidl —-> a sample interface definition with no corresponding .java files ANYWHERE

————class2.aidl —-> This is parcellable
the aidl files that exist in your src folder, have their corresponding aidl files in the aidl folder in the same package structure.

Now good news is since the aidl folder exists in your <project> folder, it will be picked up by eclipse (on a refresh). However there is still one minor issue. aidl file class1.aidl will not be automatically compiled to class1.java. To do this, we need to add the entire aidl folder as a “source” folder. Simple. do this:

add an entry like so in the .classpath file!! (ah ha)

<classpathentry kind=”src” path=”aidl”/>

This essentially says, “i have another folder called ‘aidl‘ that is a source folder”.. voila, being a source folder it will get included in auto-builds.

Beauty of this is that for class2.aidl and file1.aidl (in your aidl folder), no .java file will be created as they already exist, however class1.java will be built.

Saves a huge pain in the rear side (i couldnt spell “posterior”)!

good luck. please let me know if ive missed something.

PS <08/03/2008>

Please see Comment # 2 for further clarifications (and speculations too).  Thanks for trickybit (Comment #1) for inspring that!

Advertisements

20 thoughts on “Android Hack – Parcellable in eclipse

  1. Thanks for this! First, you have a typo in the last sentence before “posterior.” You meant to say, I believe, that *class1.java* will be built.

    But I don’t see how. What’s the difference between class1.aidl and class2.aidl, sitting beside each other in aidl/package2/, which cause one to be compiled buy AIDL and other to not be?

    I assumed I’d need to create a little ant file and “manually” launch it to get the contents of my aidl/ subdirectory correctly compiled.

    Thanks

  2. Hi,

    wow quick response. thanks for that. was doing this post at midnight :D. i will update it asap… (how do you spell posterior by the way?)

    an seconly you dont need an ant file. That was preceisely what I had wanted to avoid. It was going to be a bit of work to do all that manually. the reason is that having the entry in you .classpath takes care of that and ensures all folders of the type “src” are included in auto-build as I had discovered.

    you are right, i had thought that eclipse would have tried to compile all aidl files into .java files regardless of them parcelable or not. But this turned out not to be true. As it happened with my project, the aidl files corresponding to existing parcelable objects did not get compiled as (i think) eclipse was able to find .java files for this.

    There is another explanation, but I am not fully convinced about it, which goes as follows:

    aidl.exe has a “-b” switch that forces the aidl compiler to NOT compile parcelable aidl files. Now this rule I believe is sort of being enforced by eclipse but if the .java and .aidl files are in the same folder, eclipse complains.

    Cheers
    Sri

  3. Man I am glad I gave away that perception :D. plus your bound to learn something when you spend hours and hours in frustration!!! 😀

  4. Thank you so much for this! I had written an entire client/server IPC mechanism using sockets to work around the AIDL/eclipse bug. I was able to strip that monstrosity out and replace it with AIDL in two hours thanks to your blog.

  5. I do not see this working for me, but perhaps the example could be cleaned up.

    rather than call these files file1.java, etc, why not

    MyParcelableClass.aidl

    IMyFirstInterface.aidl

    etc

    Where are the .java files that are generated expected to appear? Under src/ or under aidl/ ? One (only) of my interface.java files is being generated under aidl/ and the other is not kicking off, presumably because it is using my parcelable class.

    Confused here…

  6. Ok, I got it working. Here is some more essential detail.

    my AIDL is simply this:

    package com.foo;

    import com.foo.MyParcelable;

    // one-way interface so the server does not block waiting for the client.

    oneway interface IMyInterface {
    // Called when a parcel of information has been received
    void localInput(in MyParcelable p);
    }

    ——- NOW, the secret is that my Parcelable implementation was fielding complaints from Eclipse for its untemplated CREATOR member. It had to be changed to the following form from the examples provided in the docs (note addition of in the constructor and definition of CREATOR):

    within MyParcelable.java:

    public static final Parcelable.Creator CREATOR
    = new Parcelable.Creator() {
    public MyParcelable createFromParcel(Parcel in) {
    return new MyParcelable(in);
    }

    public MyParcelable[] newArray(int size) {
    return new MyParcelable[size];
    }
    };

    Hope this helps.

  7. Tony,

    Thanks heaps for that mate. I had written that on a very early version of the SDK (M5 I think), earlier this year. I hadnt checked it for the later SDKs, which may explain the slight differences (or am I wrong in this??)

    Glad you got it working and thanks for posting the fixes/updates for this. Appreciate it mate.

    What are you working on anyway?

    Cheers
    Sri

  8. Hi,

    I am trying to implement the Parcelable interface using Eclipse and the 1.0 r2 SDK, and I am getting this error message:

    MyClass.java is in the way of MyClass.aidl

    I tried the project structure you described in your original post but the problem remains.

    Do you have any idea why?
    Thanks.

  9. Ok, sorry about that, I missed the automated creation of the project.aidl at the root of the project containing the necessary declerations.

  10. Good info… this answers questions I had about aidl and imports.

    But can you PLEASE turn off the SnapShot service? I mean, 1) It gets in the way, and 2) it’s 1/32nd the original screen size, so there’s no way you can read anything on it, right?

    I’d much rather see the target page title on mouseover, than an unreadable thumbnail of a page.

    Thanks for reading (or not.) I’m on a campaign to rid the world of mouseover web page previews. =)

  11. Good info… this answers questions I had about aidl and imports.

    But can you PLEASE turn off the SnapShot service? I mean, 1) It gets in the way, and 2) it’s 1/32nd the original screen size, so there’s no way you can read anything on it, right?

    I’d much rather see the target page title on mouseover, than an unreadable thumbnail of a page.

    Thanks for reading (or not.) I’m on a campaign to rid the world of mouseover web page previews. =)

    • Done mate. I am pretty neutral to it myself. If however there is “great demand” for it, it may come back 😀

      By the way, what great things are you doing with android?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s