I’m wondering if it’s possible to parcel (or serialize) a ClassLoader to send it through a Message to another process in Android. ClassLoader doesn’t implement Parcelable/Serializable.
Any hints on how to do this? Thanks in advance!
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
Class loader
A class loader is basically a hash table whose entries are keyed by class name and points to byte code loaded in the VM. Byte code loaded in the VM itself is of course off limits to Java processes, as Java does not allow you to manipulate code. Note that the bytecode has been compiled by the JIT VM into CPU-specific code and will contain memory locations and other low-level constructs.
It is possible to share class loaders (via serialization or otherwise) within the same VM, since the class loader will still be able to point to the original byte code. However, in order to serialize then deserialize into another VM, the class loader would have to serialize the byte code. And there is the problem.
Serializing a class loader
As a thought experiment, how would we serialize the code so that the other process could deserialize it?
We would have to handle this as class-sized chunks so the serialized entity has the entire class interface. We would have to ‘unresolve’ pointers in the bytecode to symbols. We would also have to copy the entire string and symbol table for the class so introspection continues to work.
What we have just defined is the class file itself (a slight difference being the initialisation vs. serialisation of class members)
Let me repeat that: A class file is the serialized version of a class.
The DEX conundrum
However, Android pre-compiles class files into the DEX. This is a single file which contains an optimized version of a JAR – classes are pre-linked with each other and all strings symbols sit in the same shared string/symbol pools. So, in Android, you the smallest sharable component is the DEX.
In many instances app or device makers create an ODEX file. This is a DEX file that has been compiled to a specific CPU and architecture (including big-endian or little-endian systems).
In Android you can think of the ODEX file as the serialized class loader.
Remote class loading
The crux of the problem is how one process can load class files visible to the original process. yorkw suggested a class loader s/he found which does something like what I have suggested. The approach is that the first process implements a class-lookup service, returning the class bytecode. However this won’t work on Android directly because of the DEX problem listed above.
Solution?
Any solution that you implement is therefore going to be based on the (O)DEX. You basically need to have your client talk to your server and request a (O)DEX file, then load it as a single entity. Loading it will return your new class loader
Now, I have never done this, and it is entirely possible that Android allows just one DEX file to be loaded scuppering this approach. YMMV
I do hope this discussion helps…
TL;DR You can’t serialize a class loader; however you might be able to persuade another process to load a (O)DEX file which would produce the same result.