Multiple targets from one Android source (the better way)
Some of you might have read my article Android: Deploying multiple targets from one project. It describes how to create customized versions of the same software and therefore benefit from multiple apps with the same featureset. That deployment with an Ant script has proven to work well. For example our GMX Mail App is available in four different customizations, for different brands, and uses a similar approach with maven.
However, there is a better way now to handle multiple targets. It is less complex and gives you even more options to customize the different targets. By using an Android Library Project, you still have the benefit of sharing resources and code, without the hacky Ant script. Remember, the Ant script would go through every Java source file and change an import statement, just to resolve the different package name of the R File. Switching between Targets required an Ant build with a refresh of the workspace. Not any more. Now switching between projects is as simple as clicking the run button in Eclipse. Especially for bigger projects this is a huge benefit, because refreshing the workspace can take quite some time.
So what is the new setup? You need to create one base project, with everything common inside, and declare it as an Android Library Project. This option is available under project properties in the Android tab. Then you create the first one of your targets as a different Android Project in Eclipse. On the same properties tab of the new project, you add the base project as a library. Repeat it for another project, which will be your second target. Now you will have somthing similar to this:
For the showcase, I deleted all source files of the custom projects. Since we want to re-use the majority of our sourcecode from the base project, we don’t need any custom-sources right now. There is one little fix we need to apply to the AndroidManifest.xml file. The Android Wizard in Eclipse uses relative references to our Activities. This does not work if we want to use our Activity from the base project, because it uses a different package than our custom project. Therefore, we have to specify the full package name to the specific Activity. In my sample the important part looks like this:
That’s it. You can now overwrite all your base resources and source files in the custom projects. Every new feature developed in the base project is immediately available everywhere. Only if there is a need for updating the AndroidManifest, you have to edit it in all custom projects. But this also means you have a fine grained control over the manifest file.
I updated my old example project on Google Code. Feel free to use it as a start for your own project with multiple targets. Feedback and contributions are always welcome.
8 Replies to “Multiple targets from one Android source (the better way)”
nice tutorial, helpfull
This looks like a nice method but i’m just wondering if there’s a way to prevent keeping duplicates of the AndroidManifest.xml for each target. Is there a way to merge them during build? Txn…
Do we have to modify the manifest files of the other projects to match the library project’s?
I’m trying your example but I keep getting a Null pointer exception when trying to run the ‘sub’ projects saying it can’t find R.string.hello resource even though hello is defined in the library project strings.xml and the ‘sub’ project’s strings.xml
Thanks. Great post. But using this method gives errors if the base project contains attrs.xml. Please see http://stackoverflow.com/questions/3432649/r-java-file-from-android-library-project-not-importing-into-application-project.
Unfortunately, I haven’t found a good way of preventing duplication of the AndroidManifest.xml. You might use a template and insert the package name at build time. But then it is not easily possible to launch from eclipse.
I used your previous method/script – this works better with SVN 🙂 I have an issue though…. debugging seems to fail. Eclipse can’t find class definitions and dosen’t stop at breakpoints!!?! Have you had the same errors or idea what I missed? Oh by the way, is the base project needed to be library-only meaning do I need two ‘custom’ projects for application A and B? Or can the base project serve as application A?
An important detail I miss in this tutorial: any JAR file referenced by the base project must be also added to the children’s buildpath.
For example, I kept getting a NoDefClassFoundError for a fragmentActivity which didn’t dissappear until I added supportPackagev4.jar to my rebranded project’s build path.
Thanks for the post!
i think its possible to use one manifest.xml
you have to delete the custom manifests and import -> general -> filesystem
select the origin xml file…
set advanced use create links in workspace (all checked) and use PROJEECT_LOC
now you linked a central xml file in your project 🙂
Comments are closed.