Reputation:
I read some documentations about classloaders, but im still not sure where and why they are needed. The Android API says:
Loads classes and resources from a repository. One or more class loaders are installed at runtime. These are consulted whenever the runtime system needs a specific class that is not yet available in-memory.
So if i understand this correct, there can be many classlaoders which are responsible for loading new classes. But how the system decides which to use? And in which situation should a developer instantiate a new classloader?
In the Android API for Intent there is a method
public void setExtrasClassLoader (ClassLoader loader)
The description says:
Sets the ClassLoader that will be used when unmarshalling any Parcelable values from the extras of this Intent.
So can i define there a special classloader so that i can pass object with an Intent which are not defined in the receiving activity? An example:
If activity A which is located in Project A (in Eclipse) defines an object which i want to send to Activity B in Project B using putExtra of the Intent object. If this object which is send over the Intent is not defined (source code in project B), then there is a NoClassDefFoundException. So can i use the method setExtraClassloader to avoid this exception? If yes, how can i decide which classloader object i have to pass? And how do I instantiate it correctly?
Upvotes: 12
Views: 16793
Reputation: 323
This is a late answer, but hopefully it will help others.
Classloaders in general, are used to load executable Java code at runtime. A good example of this would be a plugin that is downloaded from the internet. You can take the binary data from a class file, load it, and call the functions within it as needed. You do, of course, need to use an interface or abstract class that's known by the calling program so it knows how to use the class.
A custom classloader is used when the binary class data isn't accessible in a typical manor. For instance, if you have a bluetooth device that contains a class file with code implementing an interface, you would need to write a custom classloader to load the class data over the bluetooth interface.
Another reason you may want to write a custom classloader is if you want to change how the loaded class accesses other classes. You can restrict which internal classes the loaded class has access to or even write your own classes, changing the behavior of an internal class. For instance, if the loaded class uses the Java.io.File class, you may need to force it to use an internal class to access files in a different way.
In short, when you write a custom classloader, you change how a class is loaded, as well as how the loaded class will load all other classes.
Upvotes: 12
Reputation: 41
ClassLoaders aren't all that hard to understand, at least in the stock Java space. (I can teach you the ClassLoader system in 90 minutes--I do it all the time at the No Fluff Just Stuff shows.) That said, most of the time you don't need to create a custom ClassLoader--if you want to futz with bytecode on the way in, java.lang.instrument is your friend. If you want to load code from a URL, check out java.net.URLClassLoader. Between those two, the need for a custom ClassLoader is entirely nil.
Upvotes: 4
Reputation: 1007369
I read some documentations about classloaders, but im still not sure where and why they are needed.
Generally speaking, you do not need to touch the classloader system.
And in which situation should a developer instantiate a new classloader?
After about a decade's experience in Java programming. :-)
If activity A which is located in Project A (in Eclipse) defines an object which i want to send to Activity B in Project B using putExtra of the Intent object. If this object which is send over the Intent is not defined (source code in project B), then there is a NoClassDefFoundException. So can i use the method setExtraClassloader to avoid this exception?
No, because Project A and Project B cannot share code. Put the class you need in both projects. Or use a remote service interface with AIDL instead of Intents
and extras. Or do not use a custom class, but rather treat the object as a data structure (e.g., use a simple HashMap
of Strings
or something).
Upvotes: 13