Converting an existing Android application to a library is incredibly simple: All I have to do is check the is Library checkbox in the project's properties.
However, once this easy step has been applied, a much more serious task lies ahead: How to retain the original application code unchanged (as a library!), while building different applications based on it.
That is, I don't really want to add another activity, but rather re-use the original activity (now in a library), where only a few methods (in the one-and-only activity) are different in each derived application.
Is the solution really is as simple as subclassing the library's activity in each application based on it?
What caveats should I watch for?
Is there a better approach?
You will mostly have to derive new classes from the ones included in the librairy or call their methods. If your librairy has classes such as activities, applications, you can extends them has you said.
Another solution could be to isolate the code you want to reuse and plugit into other activities by dependency injection. But this framework seems an overkill to me where you can just derive new classes.
A more android specific problem could be : how to call my new activities from within my new applications. The answer here relies in intent and to use different action names to call for the extended activities.
Regards,
Stéphane
Related
Coming from Java EE to an Android application (i'm not Guru in Java EE), For a fatest load of the application, we decided to process a files asynchronously, when the application starts, we launch some asynchronous channels to read the files, then we open the main activity, the idea is the user may not go directly to the use cases which need these files, but if he go it direclty and the asynchronous read wasn't terminated, he should wait a while(what the client wanted).
My question is how to passe the Future object between activities? my team agreed for using static methods or singletons, but i really don't love singleton because its an antipattern and i don't like static methods because they behave nearly like singleton.
Trying to use parceable or serializable, but future doesn't use implement anyone of it, i tried to use RoboGuice (its based on static fields but its busniss) but its a little buggy, how can i do it in android in pretty way, if there's another idea, i will be obliged to use singleton or static methods.
EventBus can be used to send objects from 1 place to another (e.g. asyncTask to Activity). It's great and easy to use, and it will accomplish what you're trying to do perfectly.
You can create your custom object classes to send between almost any 2 classes, Activities, Services, or whatever you with.
I am working on a library in android that attempts to ease navigation using Fragments. I am having some trouble with how I can maintain the code with some upcoming changes that I want to make.
Currently I using the support library only (since this can be used in past and current version of android), but i would like to offer (and have been asked if I could offer) a non support version of the library. On top of this my has 2 version (one Fragment and the other ListFragment) so that I can support both Fragment types. I am currently duplicating code between Fragment and ListFragment as there is no way to at runtime decide which it extends from. To ensure I always implement the methods on both classes they both implement INavigationFragment so that there is no human error in missing a class, plus this let's me pass around my fragments without worrying if they are a ListFragment or a Fragment.
My question is if anyone knows of a way that I can support both android.app.Fragment and android.support.v4.app.Fragment without having to duplicate my code all over the place? I have made the core of my manager clean that it should be able to easily use the proper non-support/support fragment but I can't seem to think of an easy way to do it for the fragments themselves.
Please see here to see how I'm currently handling the support library. https://github.com/DMCApps/NavigationFragment/tree/master/navigation-fragment/src/main/java/com/dmcapps/navigationfragment
I have a few thoughts but I'm not sure if there is another way that anyone can help me out with.
My thoughts (1 being what I think is best to keep down the amount of code I have to write):
Create an Annotation Processor for my support NavigationFragment which then creates the NavigationListFragment and the non-support fragments, by changing the imports and extends appropriately.
Scrap the NavigationListFragment and make the user implement there own List gathering in onCreateView. (I hate to do this but it'll make managing the code easier).
I guess I only have 2 ways that I can remember.
Thanks,
DMCApps
I'm trying to do something clever. I am creating a weather application in which we can replace the weather API with another weather API without affecting the code base. So I started with a Maven project with multiple modules.
I have a Base module that contains the Interface class and the Base class. The Interface class contains the calls to the APIs (all calls are similar, if not exact) and the Base class contains the properties to the APIs (again, all properties are similar, if not exact).
I have a module for each of the two weather APIs we are testing with plans to create more modules for new weather APIs as we grow the application.
Finally, I have created a Core module (includes main) to implement the specific module class for the weather API I want to test.
Now, I know the simplest way to do this would be to use a switch statement and enumeration. But I want to know if there is a more clever way to do this. Maybe using a Pattern? Any suggestions?
Here is a picture of the structure I have just described:
Here is the UML representation:
This is a learning process for me. I want to discover how a real Java Guru would implement the appropriate module and class based on a specified configuration.
Thank you for your suggestions.
I'm trying to do something clever. I am creating a weather application
in which we can replace the weather API with another weather API
without affecting the code base.
Without reading further down, this first statement makes me think about a plugin architecture design, but in the process of software design, decisions must not be rushed, the more you delay, the more information you have and a better informed decision can be made, for now is just an idea to keep in mind.
I have a Base module that contains the Interface class and the Base
class. The Interface class contains the calls to the APIs (all calls
are similar, if not exact) and the Base class contains the properties
to the APIs (again, all properties are similar, if not exact).
When different modules share behaviour/state, it is a good idea to refactor them and produce base abstract classes and interfaces, so you are on the right track, but, if there are differences, those shouldn't be refactored into the base module. The reason behind that is simple, maintainability. If you start adding if clauses or switches to deal with these differences, you just introduced coupling between modules, and you'll be always having to make changes in the base module, whenever you add/modify other modules, and this is not desirable at all.
This is reflected by the Open/Closed principle form the SOLID principles, which states that a class should be open for extension but closed for modifications.
So after you've refactored the common behaviour into the base modules, then each new API should extend the base module, as you did.
Finally, I have created a Core module (includes main) to implement the
specific module class for the weather API I want to test.
Now, I know the simplest way to do this would be to use a switch
statement and enumeration. But I want to know if there is a more
clever way to do this. Maybe using a Pattern? Any suggestions?
Indeed, making use of a switch, makes it work, but its not a clean design at all, for the same reason as before, when adding, modifying or removing modules, would require to modify this module aswell, and also this code can potentially break.
One possible solution, would be to delegate this responsability on a new component and make use of a creational design pattern like the Abstract Factory, which will provide a interface to instantiate components without specifying its classes.
As for the architecture, so far, the plugin architecture still makes sense, but what if the different modules extend the base contract adding more features? One option is to use the Facade pattern to adapt the module calls and provide an output that implements an interface that clients expect.
But then again, with the provided details, this is the solution I'd suggest, but the scenario should be studied carefully and in greater detail, in order to be able to assure that these are the right tools for the job, and commit to them.
In addition to Salvador Juan Martinez's answer...
To implement a plugin architecture Java's Jar File Specification provides support for service provider interfaces (SPI) and how they are looked up.
As of Java 1.6. you can use the ServiceLoader to lookup service providers. For Java 1.5. and less you must do it on your own or use a library. E.g. commons-discovery.
The usage is quiet simple. In your case put a META-INF/services/com.a2i.weatherbase.IWeather file in each plugin module.
In the Weather Forecast IO module the file should contain only one line
com.a2i.weatherforecastio.ForecastIO
The line must be the full quallified name of an IWeather implementation class.
Do the same for the other module and you can load the implementations via ServiceLoader.
ServiceLoader<IWeather> weatherServicesLoader = ServiceLoader.load(IWeather.class);
Iterator<IWeather> weatherServices = weatherServicesLoader.iterator();
Now it depends on your runtime classpath how many services will be found. Try to add and remove module jar archives from the classpath and run your application.
EDIT
I wrote a blog about a pluggable architecture with standard java. See http://www.link-intersystems.com/blog/2016/01/02/a-plug-in-architecture-implemented-with-java/
Source code is also available at https://github.com/link-intersystems/blog/tree/master/java-plugin-architecture
One solution is you have to define the common interface with all the identified common operations. The extensions/plugins need to implement that interface and have to provide the implementation to common operations.
You can use an abstract factory design pattern to hook up the exact implementation at runtime based on the input parameters.
Interfaces and abstract classes are always good in such scenarios, Thanks.
Let's say I have a LibImplementationA that includes a LibInterfaces.
LibImplementationA contains the implementations of LibInterfaces's java interfaces .
My application uses the interfaces from LibInterfaces and the implementations from LibImplementationA.
I included LibImplementationA in my app, and I thought I could use the interfaces from LibInterfaces in my app's code. But I couldn't !
Why ?
To make my app work, I must include LibImplementationA and LibInterfaces.
So LibInterfaces is duplicated (in LibImplementationA and my app), and this seems really bad (in case of the update of LibInterfaces)
Last but not least, in my app I want to be able to switch from using LibImplementationA to LibImplementationB or LibImplementationX (that's why the app uses LibInterfaces).
My real problem is way more complex, but I need a clever idea to avoid duplications of this LibInterfaces, if possible!
I'm using Android Studio, with gradle.
Edit: for a better understanding, LibInterfaces contains communication interfaces (as simple as sendMessage(), messageReceived() methods) and LibImplementationX implements those methods using SIP, XMPP, WebSocket, Whatever.
The answer of "Why" - LibInterfaces could be protected/default scope interface & couldn't be implemented outside of that specific package.
Since the whole Android stuff is open source I was thinking about to do some minor modifications in a few internal classes from the com.android.internal.telephony package and of course then I would love if somehow my application could use the modified classes. I was thinking about replacing the classes with the original ones at runtime by using reflection or other kind of unknown java tricks :D ...maybe what I'm trying to do is impossible :( I don't know that's why I'm asking.
Note: The changes in the internal classes would not change their functionality in any way, its more about extending their functionality so even if other apps would use the modified versions it would not break them!
Why I want to do it? What I'm trying to achieve ?
Well i would like to modify the com.android.internal.telephony.gsm.CallTracker internal class so i could do proper call handling (call blocking etc..)
Maybe if you know about another way how to do what I want to I would like to hear about it :)
Note2: I know about the method when you handle the android.intent.action.PHONE_STATE, action , but its simply too late to react when this action is broadcasted. I'm really looking for a better solution even if that solution involve ugly hacks :)
As always thanks for all your replies...
You cannot do this :) I'll let you imagine what would happen if any application was allowed to freely replace core parts of the system. You can download the Android source code and you can modify it and you can upload the modifications to your phone (if your phone is rooted/unlocked) but you cannot apply such modifications with a simple app.
Changing a classes functionality (methods, byte code) after a class ha been loaded is impossible. Reflection/Invocation does not affect classes but static fields and instances only.
Your looking at a way to add additional methods or change existing methods of a running system, because the classes in question probably will be loaded already when your 'hacking' application is executed.
The only technical approach that I see is to change the classes in advance and deploy a modified system. I'm just ignoring possible licensing issues and security at the moment. But even with this way, your software would depend on a custom OS, a branch from some andorid version, disconnected from official updates, and you'd have to ask your customers to install a custom OS with, say, unknown features.
Sidenote - I'm very happy, that this is really impossible, otherwise my mobile would already be full of trojans, viruses, etc...
Romain is correct you can't and shouldn't try to change existing system classes.
That said, implementing call screening as you suggest should be possible by creating a replacement to the dialer application that handles phone calls.
Specifically the intent ACTION_ANSWER should be handled by your application, which could then either implement a dialer-like interface or open the dialer app (or any other call manager) explicitly.
There are actually ways to hack on Android framework classes, it just depends on which ones you want to hack.
You must extend the class you intent to hack on.
If you want to override package private methods and/or access package private variables you can put your class in the same package.
You can use reflection.
I've actually had to do this to work around bugs. Romain is correct, to an extent. It all depends on the structure of the code you are trying to hack on. You definitely can't hack on Android internals, but you can hack on other framework classes like Activity, View, etc.