Multiple classes extending Application - java

two classes extend Application
One class I've registered in the Manifest and am using as an Application is meant to be
Second class is my utilities class. It does lots of I/O and has a few helper methods. For I/O you need context (getAssets etc), so I reluctantly extended Application.
Note:
Everything is working as it should.
My Question:
Are there any drawbacks of using multiple Application classes? Is this even advised?
A few thoughts:
Like what would happen if I had onCreate and other callback methods defined in both the classes?
How do I register them both in the manifest even?
etc
PS: I know I can just use a field to store context in the second class.

I think this is not advised at all, because there is could only be one instance on Application (thus only one class).
I am very suspicious about what is really working. You're talking about utility class, so maybe you're using static methods that are working well. But you should use your debugger, and I'm almost certain that you'll discover that one of your classes is never instantiated.
By the way, the official documentation states that :
" There is normally no need to subclass Application. In most situations, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton. "

Related

Automatically call static block without explicitly calling Class.forName

Asume the following code:
public class Main {
public static final List<Object> configuration = new ArrayList<>();
public static void main(String[] args) {
System.out.println(configuration);
}
}
I now want to be able, to provide "self-configuring" classes. This means, they should be able to simply provide something like a static block, that will get called automatically like this:
public class Custom {
static {
Main.configuration.add(Custom.class);
}
}
If you execute this code, the configuration list is empty (because of the way static blocks are executed). The class is "reachable", but not "loaded". You could add the following to the Main class before the System.out
Class.forName("Custom");
and the list would now contain the Custom class object (since the class is not initialized yet, this call initializes it). But because the control should be inverse (Custom should know Main and not the other way around), this is not a usable approach. Custom should never be called directly from Main or any class, that is associated with Main.
What would be possible though is the following: You could add an Annotation to the class and collect all classes with said annotation, using something like the ClassGraph framework and call Class.forName on each of them.
TL;DR
Is there a way, to automatically call the static block without the need to analyze all classes and the need of knowing the concrete, "self configuring" class? Perfect would be an approach, that, upon starting the application, automatically initializes a classes (if they are annotated with a certain annotation). I thought about custom ClassLoaders, but from what i understand, they are lazy and therefor not usable for this approach.
The background of this is, that i want to incorporate it into an annotation processor, which creates "self configuring code".
Example (warning: design-talk and in depth)
To make this a little less abstract, imagine the following:
You develop a Framework. Let's call it Foo. Foo has the classes GlobalRepository and Repository. GlobalRepository follows the Singleton design pattern (only static methods). The Repository as well as the GlobalRepository have a method "void add(Object)" and " T get(Class)". If you call get on the Repository and the Class cannot be found, it calls GlobalRepository.get(Class).
For convenience, you want to provide an Annotation called #Add. This Annotation can be placed on Type-Declarations (aka Classes). An annotation-processor creates some configurations, which automatically add all annotated classes to the GlobalRepository and therefor reduce boilerplate code. It should only (in all cases) happen once. Therefor the generated code has a static initializer, in which the GlobalRepository is filled, just like you would do with the local repository. Because your Configurations have names that are designed to be as unique as possible and for some reason even contain the date of creation (this is a bit arbitrary, but stay with me), they are nearly impossible to guess.
So, you also add an annotation to those Configurations, which is called #AutoLoad. You require the using developer to call GlobalRepository.load(), after which all classes are analyzed and all classes with this annotation are initialized, and therefor their respective static-blocks are called.
This is a not very scalable approach. The bigger the application, the bigger the realm to search, the longer the time and so on. A better approach would be, that upon starting the application, all classes are automatically initialized. Like through a ClassLoader. Something like this is what i am looking for.
First, don’t hold Class objects in your registry. These Class objects would require you to use Reflection to get the actual operation, like instantiating them or invoking certain methods, whose signature you need to know before-hand anyway.
The standard approach is to use an interface to describe the operations which the dynamic components ought to support. Then, have a registry of implementation instances. These still allow to defer expensive operations, if you separate them into the operational interface and a factory interface.
E.g. a CharsetProvider is not the actual Charset implementation, but provides access to them on demand. So the existing registry of providers does not consume much memory as long as only common charsets are used.
Once you have defined such a service interface, you may use the standard service discovery mechanism. In case of jar files or directories containing class files, you create a subdirectory META-INF/services/ containing a file name as the qualified name of the interface containing qualified names of implementation classes. Each class path entry may have such a resource.
In case of Java modules, you can declare such an implementation even more robust, using
provides service.interface.name with actual.implementation.class;
statements in your module declaration.
Then, the main class may lookup the implementations, only knowing the interface, as
List<MyService> registered = new ArrayList<>();
for(Iterator<MyService> i = ServiceLoader.load(MyService.class); i.hasNext();) {
registered.add(i.next());
}
or, starting with Java 9
List<MyService> registered = ServiceLoader.load(MyService.class)
.stream().collect(Collectors.toList());
The class documentation of ServiceLoader contains a lot more details about this architecture. When you go through the package list of the standard API looking for packages have a name ending with .spi, you get an idea, how often this mechanism is already used within the JDK itself. The interfaces are not required to be in packages with such names though, e.g. implementations of java.sql.Driver are also searched through this mechanism.
Starting with Java 9, you could even use this to do something like “finding the Class objects for all classes having a certain annotation”, e.g.
List<Class<?>> configuration = ServiceLoader.load(MyService.class)
.stream()
.map(ServiceLoader.Provider::type)
.filter(c -> c.isAnnotationPresent(MyAnnotation.class))
.collect(Collectors.toList());
but since this still requires the classes to implement a service interface and being declared as implementations of the interface, it’s preferable to use the methods declared by the interface for interacting with the modules.

Is this a good reason to use a Singleton?

I'm making an Android app that will have the timetables of a local bus.
There are more than one timetable, the one that will be use depends on the day.
If it's a holiday I must use a special timetable, so I want to know when is a holiday and when is not.
The thing is that I'm creating a class that will handle this, it will try to retrieve information from memory or from a web api. Then some other classes will be able to communicate with this class, but it doesn't seem necessary to me to have more than one instance of this class, I could create just one instance and share it with the rest of the classes.
Could this class be a Singleton or it would be better if I create a normal class ?
In your case (retrieving info from memory), definitely avoid using a singleton class because it will highly likely be tied to your Activity context.
Your class will have a static reference to a class, therefore
it will be kept in memory when not needed.
singleton may be reinstantiated, or may use obsolete instance, with new instations of activities. You will lose control of the current variables.
diffent instances of the same activity class are highly likely to conflict with this class.
Examples of the same activity class several instantiation:
Change device orientation.
Running app from the webbrowser's, Google Play, file browser intent.
Besides, at some point, when you add functionality based on user reviews, your app will grow, you are likely want to refactor your class, break it into subclasses, put some of its methods into separate threads. It will no longer be easy to do.
It might seem fun while the app is small, and untested, but later, in Android specifically, you will run into a nightmite with unpredictable and hard to detect errors.
Because of Android's special way to recreate activity class, through onCreate, onResume etc. you will run into a nightmare, when the app will start living its own life.
You will no longer be able to rely on the assumption that the current singleton instantiation actually belongs to your current activity.
You may swap between orientations or run your app from different entry points (launcher, recent apps, google play), and it may reuse the variables actually prepared for a different activity instantiation.
If you need only one instance of the class, just create one instance of the class in the onCreate method - and that will make the app much more manageable.
One of the main advantages a Singleton class brings you is the fact that you are sure to have one and only one instance of an object doing some thing, and that it is instantiated only once (preferably at a specific point of your application, for instance at startup or only after certain other operations have been performed)
An example could be for instance a cache implementation: you want to make sure that all classes that need a certain cache read and write from the same object, that maybe is created and filled with information at startup time.
Your does not seem to be the case, unless you fetch the information you need when your application starts and then you keep them memorized for some reason: in this case you want to make sure your information is fetched one and only one time, to avoid wasting memory and elaboration time. Also, a Singleton is fine if you need to do some kind of operation when your class is instantiated, like opening a connection that then stays open.
On the other hand, if you just need a class with some method to call some external apis or database and you don't need to memorize any information in it, there is no reason to initialize a singleton.
If this is your case, why don't you try some static class/methods? They can be called like normal methods directly on the class with no need to instantiate objects or keeping a state, saving memory and avoiding side effects.

Extending application or using singletion?

I have an android project where i have different objects that one or more of my activities need to acess now i was thinking of creating a subclass of Application however under the documentation of Application it states the following:
There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton.
My question is fairly simple is it best pratice to use a static singleton class to contain all of your objects ? or am i right to assume that extending application is a better option?
To answer your question I would use a singleton container to access these objects, initialize that class with a context by application context (there are very big chances you will need a Context); but then you will see it's kind of hard to maintain these and the singleton container.
To solve this object graph issue, I would use some IoC: RoboJuice, AndroidAnnotations or Dagger are really cool and they provide much more. Each of them handles this issue different, but you don't have to worry about that.
I hope it helps!

accessing static method across plugins

I have two plugins pluginA, and pluginB, which are using SDK from a platform C. Obviously pluginA and pluginB would not be able to access methods from each other, and any communication between pluginA and pluginB must be via C.
pluginA has a utility class utilA , which has a static method getMethod() which will be used in pluginB. and returns an object of a class which is also in pluginB itself. I can create any interface/factory class , in platform C, so that this communication can be done.
Can someone suggest how to tackle this problem.
This is a Factory design pattern. The factory should be a resource accessible from the SDK to all "plugins" and the SDK should decide (perhaps with a settings file or annotations) which plugin becomes the supplier for the factory.
One other design thought. I prefer to use interfaces as the output of a Factory object. That way one class can implement the interface any way it likes, and every other class (no matter when created, or how loaded by the ClassLoader) can use that factory. This may save you a bunch of headaches at testing or runtime.

How can I run my code upon class load?

Is there a feasible way to get my own code run whenever any class is loaded in Java, without forcing the user explicitly and manually loading all classes with a custom classloader?
Without going too much into the details, whenever a class implementing a certain interface read its annotation that links it with another class, and give the pair to a third class.
Edit: Heck, I'll go to details: I'm doing an event handling library. What I'm doing is having the client code do their own Listener / Event pairs, which need to be registered with my library as a pair. (hm, that wasn't that long after all).
Further Edit: Currently the client code needs to register the pair of classes/interfaces manually, which works pretty well. My intent is to automate this away, and I thought that linking the two classes with annotations would help. Next, I want to get rid of the client code needing to keeping the list of registrations up to date always.
PS: The static block won't do, since my interface is bundled into a library, and the client code will create further interfaces. Thus, abstract classes won't do either, since it must be an interface.
If you want to base the behavior on an interface, you could use a static initializer in that interface.
public interface Foo{
static{
// do initializing here
}
}
I'm not saying it's good practice, but it will definitely initialize the first time one of the implementing classes is loaded.
Update: static blocks in interfaces are illegal. Use abstract classes instead!
Reference:
Initializers (Sun Java Tutorial)
But if I understand you right, you want the initialization to happen once per implementing class. That will be tricky. You definitely can't do that with an interface based solution. You could do it with an abstract base class that has a dynamic initializer (or constructor), that checks whether the requested mapping already exists and adds it if it doesn't, but doing such things in constructors is quite a hack.
I'd say you cleanest options are either to generate Code at build time (through annotation processing with apt or through bytecode analysis with a tool like asm) or to use an agent at class load time to dynamically create the mapping.
Ah, more input. Very good. So clients use your library and provide mappings based on annotations. Then I'd say your library should provide an initializer method, where client code can register classes. Something like this:
YourLibrary.getInstance().registerMappedClasses(
CustomClass1.class,
CustomClass2.class,
CustomClass3.class,
CustomClass4.class
)
Or, even better, a package scanning mechanism (example code to implement this can be found at this question):
YourLibrary.getInstance().registerMappedClassesFromPackages(
"com.mycompany.myclientcode.abc",
"com.mycompany.myclientcode.def"
)
Anyway, there is basically no way to avoid having your clients do that kind of work, because you can't control their build process nor their classloader for them (but you could of course provide guides for classloader or build configuration).
If you want some piece of code to be run on any class loading, you should:
overwrite the ClassLoader, adding your own custom code at the loadClass methods (don't forget forwarding to the parent ClassLoader after or before your custom code).
Define this custom ClassLoader as the default for your system (here you got how to do it: How to set my custom class loader to be the default?).
Run and check it.
Depending on what kind of environment you are, there are chances that not all the classes be loaded trouugh your custom ClassLoader (some utility packages use their own CL, some Java EE containers handle some spacific areas with specific classLoaders, etc.), but it's a kind of aproximation to what you are asking.

Categories

Resources