What would be the right way of including smaller android apps, into one bigger if requirements are the following:
little apps should be loosely coupled and should be developed separately
bigger app should handle some common things, instead of each little app do it for itself.
bigger app should now something about state of little apps, in order to do some decisions.
First thing that comes into my mind is some sort of plug-in pattern (although I don't know much about it, so I could say something wrong), so that each little app should implement some common interface, and big app should use that interface when dealing with component.
Is that right approach?
Is this right way of thinking considering android as a platform?
Your best bet is to make each sub app a "library." You create a workspace in Eclipse and create a new Android project and mark it as a Library.
You do that for each sub app.
You then have a non-library application that imports each library and uses each as part of the full application.
This means you don't need to worry about writing a plugin interface, etc.
Also if you follow this sort of pattern, when you create a free vs paid application, you are able to just add another application and remove / change functionality as that one all needs and compile both from the same code base.
Update
Take a look at http://developer.android.com/tools/projects/projects-eclipse.html for some decent documentation.
This shows how to create both types of projects and how to reference them in your manifest which is the annoying part.
Update2
From comments it was asked if you can use a library Activity in a main application that imports the library.
You create an Activity in the library
com.example.myapp.library.MyActivity
Then you add details to your manifest
<activity name="com.example.myapp.library.MyActivity">
This then let's you use it there. You can even use a library Activity as your main startup Activity if that's what you need.
You can also extend a library Activity by changing your manifest to
<activity name="MyNewActivity">
Then create a new activity
class MyNewActivity extends com.example.myapp.library.MyActivity
Then just override what you want, call super to access your library method if desired, etc.
Feel free to ask questions.
Related
The way I see it, there are a few options using Android Studio:
Add a new module for Android TV, and create a common module to share some of the code, but mainly re-write most of my code for Android TV.
Add one or more Android TV specific packages in my existing application code; add the Leanback manifest intent filter for the Android TV main Activity, and finally do manual checks in code. Some of the existing stuff can be re-used on Android TV, and some areas will need to be re-written.
What do you think is the best option?
I personally think that the second option is the best, as it's significantly easier to do, but it does have a few disadvantages, i.e. a larger APK size.
It really goes down to your project, how it is built, how big it is, and so on. In a general sense, each option has its own advantages and disadvantages.
EXTENDING THE SAME PROJECT
You can decide to share your code base and add some TV-specific classes to your existing project. This allows for a faster bootstrap for sure, since you have all the code you need right there. Plus, to the end user, the Play Store entry will not change, so you will benefit from the same ratings, downloads, visibility and so on. The downside, in this case, is the risk of your app becoming monolithic and thus, harder to handle.
CREATING A NEW MODULE
On the other hand, going for a separate project "forces" you to write common modules, which (to me) sounds like a good thing. You will have a longer bootstrap if your code/project is not modular enough, but in the long term it will pay off. Also, the APK of your TV application will benefit too, since it's going to be smaller. You will have a different Play Store entry, but that could be a downside as well as an upside. Finally, I think it feels refreshing to work on a separate project once in a while, so this is a totally subjective plus :)
In my company, we decided to go for a separate project/module. We wanted to modularize some common components, so it felt like the right time to do so. That alone was a good reason for us, and we did not regret it. Also, we had the chance to experiment with a new project structure, which involved using a bus (Otto) and a job queue (Path's).
All in all, it's up to you and to your project. I will try to add as many other points as I can.
My scenario
I have to implement a "modular" android app. There is a core module from which I should be able to invoke other modules. Each module provides a different feature to the user. Imagine I am making a city guide, then one module may contain a map with POIs, another one an event calendar and a third one pre-defined city guides. The modules contain views to be loaded in activities of the core module (like dashboards where each module puts its item/picture). They also contain activities which should be invoked (like when a user taps an item on the dashboard). As far as I know, I will need a database and/or preferences only in the core module. The "plug-in modules" use classes (utilities) of the core module, e.g. when connecting to the backend.
My solution on iOS
For iOS, I achieved this with targets in XCode. I have one project and depending on the customer's needs I compile only the relevant modules. It would be even better if the user can install modules whenever he wants, without the need of reinstalling the "core" application.
My problems on Android
In SO, I already found various solutions like library project, switching from Eclipse to Android Studio + something, using package manager and broadcast receiver... But I still don't understand... How is the modularity of an android application to be achieved?
Here are some concrete problems that I see:
Libraries: My modules all use classes of the core module, so they are not independent. I achieve the modularity by using interfaces/inheritance depending on the flexibility that I need.
Broadcast receiver: This seems to be everything else than recommended. See, for example, here or here.
What I need is, at least, to be able to use the same code for delivering app with features A and B to one customer and with B and C to another one. And, until now, I have no idea how to achieve it.
PS: I don't want to use scripting, I am not familiar with that.
I don't see this "modular" app as anything different from one app, with several packages, each containing discrete functionality, that is adapted to some list of settings or external parameter (either provided by the user or you).
My approach would be to have a "main" package. That package would contain the shared functionality you mention above and serve as the hub for your application. I would then create separate sub-packages for the different "add on" functionality. This allows you to still use the code in your main package with a simple import statement. From your description these additional functions should probably be implemented as a Fragment. A Fragment is almost a stand alone application with the exception that it is "hosted" by an Activity. Depending on how these add on functions are used (I cannot tell if they relate to the UI, just background processing etc) you could easily have 3 of 4 different fragments and choose to load only 1 or 3 or 2 of them at runtime.
To control which parts of the code are used I would just set up a simple switching class (it could even be part of the first activity launched, I cant tell from your description above). Here I would check for some setting indicating which parts of the app will be "active." This could be easily defined using SharedPreferences to store a specific configuration, e.g. use A and B, prior to delivering the final project. You would then just initialize the fragments you need and display them either (1) individually in a Fragment layout element or FrameLayout; (2) collectively in some other view structure like a ViewPager.
I follows your links on the BroadcastReceiver and I am still not sure why they are "everything else than recommended." Used correctly a BroadcastReceiver is very useful. I tend to use a LocalBroadcastManager along with a BroadcastReceiver to notify other sections of the app when some AsyncTask, e.g. downloading a lot of data, is complete. These parts of the app can then access a local database or process the information downloaded on their own time. I wouldn't use a BroadcastReceiver to modulate parts of the app if that is what you're looking for. I would instead just use a SharedPreference file to set the configuration at runtime.
If you need modules like facebook sdk or something like that better use library project. If you use Idea or Android Studio there is such thing like Module. If I need some modeles in one app I prefer just put in different packages like com.appname.model, com.appname.ui and so on. Broadcast Receiver isn't about modules. As I know there isn't analog of ios target.
This is more of a fundamental question I suppose. I currently have in the market one app that I have separated in two projects. One project (with it's unique package name, obviously) does not have Google Ads and is not free. The other project has Google Ads and it's free.
Both projects are exactly the same. Same functionalities.
When I want to add a new functionality, I have to work on both projects, making then the release of my app slower, since I am basically control-c/control-v what I did in one project onto another. And sometimes I just forget something, so I have to fix the issues...
So, basically, I am wondering if there's a better way I have to manage that?
Maybe creating a rather intelligent script that will build the application depending on what I want (i.e: if it's ad based version, should use the AndroidManifest that declares the AdMob Activity)
Or maybe create a library? But I don't think this approach would work.
Looking forward for inputs.
Regards,
Felipe Caldas
Yes, a library project is exactly what you want. Put all the functionality in a library, and have two very thin shells for each of your app types that make calls into the library. As you noticed, duplicating the code is error prone and at best just extra work you shouldn't have to do.
See: Managing Projects for details. That page even mentions your exact scenario:
If you are creating an application that exists in both free and paid
versions. You move the part of the application that is common to both
versions into a library project. The two dependent projects, with
their different package names, will reference the library project and
provide only the difference between the two application versions.
I am very new to eclipse and android developing in general and need help with the following. I have built two android projects in Eclipse with the android SDK:
"ORF401 Project" - targets Android 2.2 platform
"Map Project" - targets Google APIs 2.2 platform
I have followed the steps as specified by the standard Hello World Google Maps for android tutorial and have gotten the Google map to display on the emulator when I run the second project.
I have a menu set up in the 1st project for which one of the options is to load the map. However, I'm not sure how to load the map within this project since only one build target can be specified for each project, and so I cannot specify the Google Maps API as a (additional) build target. Is there a way to call the main .java class from the second project within the first project? I see where a reference can be made to the 2nd project under the project properties, but I'm not sure how to make use of this. One possible solution I found on the web was to add the following code under the switch case in the first project:
Intent intent = new Intent(this, {googleMap}.class);
startActivity(intent);
I presume this would require an additional googleMap.java class in the first project and also another activity, but I can't get it to work. Can anyone make a suggestion as to how I can accomplish this?
If the code for either or both projects would help, I'll be happy to post it. Thanks
The main idea with projects is to have one project per application that does some thing.
I assume your application needs to do something with maps, as well as something else. There is no need to split those ideas. Keep them in one project, because they make up one single application that you develop.
First thing I would suggest - read carefully about activities and intents. Head to http://developer.android.com - everything's clearly explained.
With that all cleared up you will see the point in making some button, which, being tapped, opens a new screen with the map feature that you've developed. And then let's you go back or do something else, like open a new screen, a browser, etc.
And give up trying to call the other project from a different one :) It's not the way I think you want to do stuff.
Just to make sure I'm not misunderstood - of course you might want to have two projects. But those will most probably result in two separate applications. Luckily, applications may also interact by intents, or content providers, or a couple more. Just see how Contacts app takes you to GMail app if you want to send a mail. If that's what you want to achieve - still need to read about intents.
edit:
Here's the link I mentioned about in the comments:
http://android-developers.blogspot.com/2010/07/how-to-have-your-cupcake-and-eat-it-too.html
It explains how to achieve the 'additional target' that you would like to have.
There are ways to call a class from one project in another project, but there are bigger problems here. The first project can run on any Android device. The second, however, requires Google Maps APIs. You won't be able to invoke it anyway, because it can't be installed unless you're in an environment that supports Google APIs. There really is no benefit to doing this, unless you have additional functionality in project 1 such that it can exist without project 2.
I would suggest using the Intent method rather than trying to hack something together that allows you to access another class. Regardless, though coupling these two together like this seems overly complicated and error prone. I would suggest simply embedding the mapping functionality in project 1 and requiring Google APIs. Most mainstream device support them anyway.
If you're married to the idea of having two separate projects with different build targets, I would suggest looking into using BroadcastReceivers with a custom intent that you broadcast from application 1. I don't believe startActivity will work across application boundaries because of class loader issues, but I could be wrong about that.
Hey! (Apologies for the long post here)
I am writing a few applications which will be based off of essentially the same code.
Each application will have its differences, some will have new activities, all will have different resources assigned.
I am attempting to use an Android Library project so that I can place all of the common code in one place, so manjor changes only have to be made once and all projects will be updated.
Now, the resources are an easy solution, as I can just define each resouce in the main application and these will override the ones in the library project as long as naming conventions stay the same.
Now, my question is how do I do the same but for classes? For example, ill have a base view as a wrapper for common code across all views. in this, i launch various activities. What if all three applications need to launch a different activity as they will contain different UI and features? How would I go about this? The library project will never know that the main project wants to use a different activity, as its already been compiled.
I have a couple of solutions I have thought up, but I want to know if anyone else has some ideas? It would be of great help for any feedback here:
The Activity in the Library Project that is to be launched stores a reference to the class to be loaded, which will be defined in the main application at its launch. This was when the library project calls this activity, it can load what its been told to.
I leave all functionality that will not change inside the library projects activity. I then extend this activity, and override the onCreate to do what I need here (such as loading different layouts, setting up views, etc). Now this has a drawback, as I have to define most of the entry points in my main application rather than in the library project.
I hope you follow what my issue is here. Please ask if I have explained this poorly.
Thanks,
Adam
Or more simple: Should you use inheritance or composition to achieve that kind of flexibility?
I had this kind of structure quest as well. Usually you would solve it by reusing a applicable pattern & break the necessary code parts in smaller pieces. I.e. if you know the difference are views, then extract that into some distinguished classes that will implement against an common interface and refer to the interface in your base activities.
Some links for you:
http://tiedyedfreaks.org/eric/CompositionVsInheritance.html
http://mindview.net/Books/TIPatterns/
http://en.wikipedia.org/wiki/Decorator_pattern - maybe applicable in your case
At least from how I understand your question, this is more of a OOP Design question.