Build configuration management in Android / Intellij / Jenkins
This question might be subjective, but I think Stackoverflow is still the best place to ask:
The problem domain is "advanced Android programming". I do not need information how to set up a single Android project, how to use library projects, or how to use ANT to build a normal project.
Assume you got a running App, an ordinary Android project (IDE of choice is IntelliJ, but that should not really matter) build by Jenkins / Ant / Proguard. The result of this build is a final APK you would put in the Play store.
Now imagine you need this App as a free and a paid version. No problem so far, simply put all shared code into a library project, and create two child projects, one with an App.java enabling license checks, the other one eg limiting the usage.
Now imagine you want to target Amazon as well, maybe have a press release version, etc. So your code starts to diverge, with still a lot of stuff shared, but certain parts are specific to eg the market you target.
In C# there are "conditional compilation statements", like "IF PLAY_STORE ...". Is there anything similar for Java / Android. Also, do they play nice with ANT and the build process.
But I am not limited to conditional compilation. The "one project per market" approach is a different one. I am just trying to get a feeling of how you manage these various "build configurations" in a manner that is sustainable. Meaning it works for 15 projects, targeting 3 markets in 2 flavors (FREE and PAID). I hope you see what I am hinting at. The code is very very similar for all Apps, but with the example above I will have 90 different APKs - with these numbers the "manually commenting in source code only needed by this build, etc" just does not cut it anymore.
So any tips, tools, search words, experiences with these problem domain (eg MAVEN, would it help me with any of it, or is ANT + scripts generating build.xml be better). Another example, if I have a "real" Android project for all target markets, this would allow me to do almost anything. But of course, on the downside, if I add a new page in the lowest level (eg a imprint page) I would need to go into 90 Manifest.xml to add the page...
Thanks for any help with this, Chris
PS: I will add some links I find regarding this topic at the bottom, if anybody comes across this question while there are no answers, this might be a "first read this" section
http://www.asyncdev.net/2011/02/android-dev-prod-builds/
http://www.slf4j.org/ (related in the "put JAR in to provide IMPL" way)
(The SLF4J is just a nice approach to reduce dependencies and provide configuration during deploy - by simply adding a different JAR. To use something like this might be overkill for your own projects, but it would be one way. Eg for license write interface and a bit of code like SLF4J, then provide either PressRelease.jar or Productive.jar in Lib folder during build, changing how the app behaves...)
You should definitely take a look at
ant
- take a look at our presentation at droidcon
here: http://skillsmatter.com/podcast/agile-testing/building-your-app-for-multiple-app-stores) Gradle
(aka "new build system") - this will help you with easier build conditions and have slightly better IDE integration (with new Android Studio
) see more information here: http://tools.android.com/tech-docs/new-build-system) UPD: As I see, you're already using LP for you projects. Some tips for making process this easier:
Use manifestmerger.enabled=true
Take a look at github.com/onepf/OpenIAB
This question is somewhat opinion based since in a complex project there are always more than 1 suitable solutions.
Preamble
I will try to explain some principles I used to deploy Linderdaum Puzzle HD. The game has paid and free versions which differs not only in code, but in UI and in game content.
The game is released for two platforms and several stores (which all have different authorization mechanism):
Android:
Blackberry OS 10
Windows
This gives us 8 different distribution packages.
Environment
Our production toolchain is based on git
and TeamCity
. No special tools (like Maven, Gradle) are used.
Solution
The end-point of our workflow is TeamCity project page where we have all build configurations corresponding to 8 distribution packages plus some additional builds for debugging (ie with additional checks and logs). Any package can be built via a web-interface from anywhere in one click.
For every package there is a git
branch name (shared by some packages) so the TeamCity
knows from where to pull the sources. Currently we have this branches:
remotes/origin/master
remotes/origin/release300-blackberry
remotes/origin/release300-master
remotes/origin/release300-paid_apps
remotes/origin/release300-paid_apps_androidpit
Here release300
represents a version of the game. We have many archive branches for these. These are not development or feature branches - they used only to hold the changes for the particular game package. Ie in paid_apps
there is more game content and paid_apps_androidpit
contains AndroidPit licensing library.
The development happens in master
and in feature branches that are merged back to master. Then a merge process takes place. The directions of merge are (and only these directions):
master -> release300-master -> release300-paid_apps -> release300-paid_apps_androidpit
-> release300-blackberry
Ie, release300-paid_apps_androidpit
has basically the same content as release300-paid_apps
, however, it adds some new features (like licensing library, etc). And release300-blackberry
is completely separate since it has to target devices with an unusual screen aspect ratio 1:1 and has a UI of the special design. So, these 5 branches are used to build our 8 distro packs.
We never merge changes from these release branches back to master. The bugfixes are propagated in the same direction.
Every package has its own script file, Ie build of the free application for Google Play is as simple as calling the Python script BuildAndroid.py
on branch release300-master
.
The same idea applies for all other packages: use just a single-line TeamCity command line build runner.
If you're stuck with ant
for reasons you can't control, consider using filters and tokens. You can have .java
files generated from templates that correspond to configuration or business logic for each type. Here's an official example:
<copy file="${build.dir}/version.txt" toFile="${dist.dir}/version.txt">
<filterset begintoken="%" endtoken="*">
<filter token="DATE" value="${TODAY}"/>
</filterset>
</copy>
This will replace the text @DATE*
in ${build.dir}/version.txt
with the current date and copy the result to ${dist.dir}/version.txt
. This, along with some smart branching, can give you a half-decent preprocessor. The downside is, of course, that it's really slow ( ant
in general is, this even more so).
I really want to be able to recommend Gradle, since it has this functionality built in (product flavors) but unfortunately that's not a serious option while it's under active development. Maybe in a few months but not now.
链接地址: http://www.djcxy.com/p/14738.html上一篇: 狮身人面像:让课堂出现在TOC上