I think I have found the solution.  Actually, there are a couple of
options.  The first is to not case plugin objects to an interface at
all, and just call all methods using reflection.  This works as a
fallback, but is obviously pretty ugly, cumbersome, and slow.  The
other option is to ship the interface classes down with the plugin,
but in a separate dex file.  Each time I want to release a new version
of the interface, I put the new interface classes in their own dex
file, and ship that along with the plugin.  So now, instead of the
plugin just consisting of implementation.jar, it has interface.jar,
interface2.jar, and implementation.jar.  To load the plug in, I create
a DexClassLoader that has these jar files on its classpath.  The
reason this works is that unlike when I was compiling the interface
classes into implementation.jar, the implementation classes are not
compiled assuming that the interface classes will be found in the same
dex file.  So, the class loader ends up doing what I was expecting it
would do all along: use the version of the interface that was already
loaded by the client, and if that doesn't exist, look elsewhere on the
classpath for the interface class definition.  This does mean that as
I extend my interface, my plugin will have to ship with more and more
jars, but I think that's a lot more palatable than using reflection.
And, I only have to ship down interface jars that are newer than my
oldest supported client, since once I am sure that all of the clients
have compiled in a given version of the interface, I no longer need to
ship it down with the plugin.

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to