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!
17 Comments »
Leave a comment
-
Recent
-
Links
-
Archives
- October 2009 (1)
- August 2009 (1)
- May 2009 (1)
- January 2009 (1)
- December 2008 (1)
- November 2008 (1)
- October 2008 (1)
- August 2008 (1)
- June 2008 (1)
- May 2008 (2)
- April 2008 (1)
- March 2008 (2)
-
Categories
-
RSS
Entries RSS
Comments RSS
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
Hi,
wow quick response. thanks for that. was doing this post at midnight
. 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
Glad you know what you are talking about!
Man I am glad I gave away that perception
. plus your bound to learn something when you spend hours and hours in frustration!!!
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.
Greg_G
Mate glad someone found it useful
My first real contribution to the world I guess!!
Cheers
Sri
Thanks a lot for this! Much needed!
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…
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.
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
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.
Ok, sorry about that, I missed the automated creation of the project.aidl at the root of the project containing the necessary declerations.
Howdy Jonathan,
Sorry for the late one mate. Just checked both your comments. I thought Il check out the latest SDK and try it out again. So is it working fine for you now?
cheers
Sri
Howdy,
Mate did this one workout ok for you?
Cheers
sri
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. =)
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?