I am facing problem. I need to build one app in two ways, first build is for development (testing) use, second build should be production version. Are there any ways how to do it programatically? (with some build engines) I mean that both apps shloud run on one device at the same time if possible. Both version are APK from one Android project.
Thanks
Personally I use this to determine whether I am in debugging mode:
final PackageInfo pinfo = getPackageInfo(ctx);
final boolean debugMode = (pinfo.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
This code is based on the debuggable
attribute of the Application
tag of the android-manifest.xml
:
If this attribute is explicitely set to true
debugMode
will be set to true
.
But if it is explicitely set to false
or not present in the xml (implicit values), debugMode
will be set to false
.
Doing this way you cannot run both app on the same device at the same time as two APK need two different package name to be installed concurrently. So you have to build two eclipse projects, each one having its own package name (for example com.example.myapp.debug
and com.example.myapp
), and why not using a common lib ( com.example.myapp.common
) that would contain almost all your code:
com.example.myapp.debug
has its debuggable
flag set to true
and com.example.myapp
has its debuggable
flag set to false
As far as I see, you really need to create different applications from you base code. One way to get this done, as I did it, is to use Ant script that copies the entire project source into another directory, say "testing", and while doing so, replaces (eg using copy filtering) certain values from XML files, like from AndroidManifest.xml. One of the first things to replace is applications package that needs to be unique for each app. The Java classes like Activities can still reside in the original packages, their names in AndroidManifest.xml just need to be absolute. Once source has been copied and filtered, you can use Ant's antcall task from the main build.xml to build the customized app. So at the end, you can say eg: "ant -Denv=testing build" and you have an APK that can be installed next to your production version.
Another alternative is to use Maven that's Android plugins support project overlaying. And of course you can use library projects, see: Android – multiple custom versions of the same app .
I think that the easiest solution is to use some kind of source control tool for this purpose. There are so many good reasons to use source control, that I believe that most developers already use it.
Summery of solution:
Description of solution.
I personally works with GIT, I believe that this approach will work with other SCM tools, but I didn't test it.
I have 2 repositories, one for development and one for production (You can get the same effect using production branch, but I preferred different repositories, since I never know when I'll have another developers, and I don't want to give anyone (including me) the chance to do a mistake with the code without having a backup for it.
All you need to do is to set different package name in the manifest file in each repository, for example:
Production manifest package name - com.foo.appName
For each activity there is a need to use the absolute path rather than the relative approach. Since there is no real option that you will change your package name, and if you do, all the changes are in the manifest file, I don't think that there is almost any drawbacks with this approach.
Then every time that you pull your changes from the developer repository to the production one, there should be a "conflict" on those lines in the manifest files, but actually there will be a conflict only on the first time you pull the code, afterwards the merging tools knows which line you prefer in the production repository.
After using this approach for some time I discovered that there is a problem with the generated R file.
The problem: R file is being generated with package name as defined in the Manifest file in the package attribute. Then all references to R file cannot be find (The package name of the source files is differed from the package name stated in the manifest file).
There are 3 solutions for that problem:
The Good: This solution is the most robust one, and I suggest you to use it (didn't try it myself though). The idea behind this solution is to generate the R file into a different class name than the one stated in the manifest. In the manifest the package would be dev.com.foo.appName but the R file will be generated to the com.foo.appName. In order to achieve it please follow this answer
The Bad: Do NOT use this solution, it is really bad, I'm stating it here that you could avoid it. In each file that using the R file add the import to the R file with the package name is in the manifest. This is a very bad solution, since you will enter a lot of unrelated code, you will need to change it in the production environment, and for every new class you will need to remember to add it.
And the Ugly: It is better not to use this solution since it is a kind of a hack. This solution is useful only for mature apps that don't have lots of changes in their resources. When ever you change your resources the R file is being generated again, then it is generated to the package name as in the manifest. All you need to do is to change the package name (in the manifest) to be as in the production environment, clean the project, build it again, and change back the package name into the development environment. Then eclipse asks if to change configuration and you choose not to. This way, 2 R files will be exist, one with the development package name and one with the production one. Since in mature apps there are not much resources changes, you will be doing so once in a while. You won't be able to forget about it, since in case that you change a resource you will start seeing weird bugs.
I know question is late, but I will answer.
You may use Gradle .
In build.gradle file you may define separate buildTypes
like this:
buildTypes {
release {
runProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
test {
applicationIdSuffix ".test"
versionNameSuffix "t"
debuggable false
}
By set applicationIdSuffix
for may install test and release build on one device
For more info go to http://tools.android.com/tech-docs/new-build-system/user-guide
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.