Strategies for Multiple Android Products with Eclipse and Git
Problem: What’s the cleanest, easist way of sharing code between multiple “products” within a given Android app?
Background: An Android application may have free and paid versions. Both have some common code and other files, but also have specific code and some files must differ between the two versions, such as the Android Manifest. When bugs or features are added in one version of the product, it would be nice for those changes to be applied to others if appropriate. This is similar to the “one product multiple versions” workflow, but different in than specific well-known files will always differ, and the requirement of merging between the concurrent branches (at least for me) is far more frequent.
- Simple to migrate code from one product to another.
- Easy to isolate code which should be shared and code that belongs to a specific product.
- Relies on SCM.
- Unlikely to let unwanted changes to slip between versions.
My Current Approach:
I’m working on my first free/paid application and I’ve decided to represent the two products (free, paid) as branches in a git repository. In this case, I’m using master for free. Since the Android market requires unique product IDs for each product, I use a Java package namespace that corresponds to the product ID for code that only belongs to one product, and a general Java package name for common code. To migrate code from one version to another, I make careful commits of only the shared java namespace and use git-cherry-pick. For now I’m using the command-line rather than egit. I find it’s best to first get familiar with a particular git feature via the command-line tools. Then any troubles encountered when using the GUI provided by egit can be better understood.
This so far is working out acceptably, but it’s not perfect. It can be hard to remember to specify commits for specific in-common code, as required by cherry-pick. Also, depending on how modular the code is, there can be a lot of refactoring to keep the code bases in-sync.
Another approach I may take in the future is to move all common code into separate Android library projects, and only have product-specific code live in actual project associated with the product. This will reduce the amount of cherry-picking required. On the downside it seems that the ADT Eclipse plugin has a proprietary way of managing code in Library projects and changes to library code does not automatically propagate to downstream projects, until the entire workspace is rebuilt. I’m hoping there is something I can do to fix this, because using the ADT Eclipse library feature is not very useful with this restriction.
Google searches didn’t turn up much for me, but I’d love to know what techniques others are using to solve this problem…