I want to build an app with different configurations. Let's say there are two flavors, A and B, which depend on different third-party libraries to perform similar tasks. I want to offer a default configuration on Google Play which comes with a separate launcher for each flavor. Both launcher instances should share local data. However, I also would like to keep the option to build and ship just one of the flavors without including the third-party libraries required for the other one.
From what information I've found, I could either use a single flavor with two launchers, losing the option to build just for one of the third-party libraries. Or I could use two flavors, but would have to separate the whole project into multiple apps with separate ids which would have to be updated separately, presumably require more storage and require some kind of workaround for sharing local data.
So, is there a way to build multiple flavors into a single app bundle with separate launchers or a similar solution for these requirements?
is there a way to build multiple flavors into a single app bundle with separate launchers
I am assuming that by "flavors" you mean product flavors in the Android build system. If that is correct, then... no, sorry, there is no simple option for this.
or a similar solution for these requirements?
It might be possible to pull off something like this with a careful subdivision of your app into modules. You would have three app modules β I will call them a, b, and ab after your naming system. Those would be as small as possible. Most of your code would reside in a series of library modules. In particular, code tied to each third-party SDK would be isolated in its own library (or libraries). a would link to library modules tied to one SDK (plus common modules), b would link to library modules tied to the other SDK (plus common modules), and ab would link to (probably) everything.
Related
I'm developing and app which will (during the development and testing process but NOT in the final version) require slightly different functionality in different .apk release files.
There are few issues in this particular case:
different "testing" APK versions shouldn't contain ANY of the code and resources (so no shared strings and images) from other APK versions (for security/reverse engineering reasons cause different people will have access to different APK versions)
at the end of the development process the app will contain all/most of the features from the "testing" builds.
the app uses multiple modules (developed by different teams)
there might be a few (between 3 and 10) of those versions, all developed concurrently by multiple developers in the same project on the same repository.
The goal is to make it as easy to maintain (including UI/integration tests and CI) as possible. Is there any way to achieve this? We did some experiments with different build variants and flavours + no-op modules/methods but it seems a little bit complex. Any alternative suggestion will be welcomed.
Your question is indeed too broad, I think there is no general solution to your problem because it's too complex, and without knowing the details of the project it's even more difficult to tackle. Actually, your problem sounds much more like an organizational one rather than a programming-related one, the only "solution" I see is to address specific issues.
1. No VCS, no party
there might be a few (between 3 and 10) of those versions, all
developed concurrently by multiple developers in the same project on
the same repository.
I would start by defining your VCS flow, because without a version control system I'm afraid you and your team(s) aren't going anywhere. If you were to use git (don't know how this would be done with other VCS), you would have a few options:
Each feature (team) has its own, long-living, feature-branch. The common code shared by all teams is kept on a develop-branch, on which each feature-branch periodically rebase. You would need to setup your CI to build test apks and run automated tests for each branch. At the end of the development process everything gets merged into master (or develop, or whatever). The advantage would be that each feature (team) would work on a sealed portion of the project and will be able to handle test releases and automated tests autonomously. The disadvantage would be that the common part of the codebase (develop-branch) needs to be handled very carefully, otherwise you might get conflicts-hell.
The whole project is developed on a common develop-branch. Each feature is developed with small increments, each member of each team branches from develop-branch and merges every iteration back on develop-branch. The advantage would be: different features can potentially depend on each other, conflicts are less likely to occur, CI has simpler configuration. Disadvantage: teams are less independent, releasing different apks requires a strategy.
2. Define dependencies
In order to choose a proper strategy, it is crucial to define clearly the dependencies between the features. Would it be possible to have truly parallel development of each feature?
This depends entirely on the specification of the project. For instance, if you were to develop an e-commerce app, you might end up having feature domains like user account, products catalog, orders processing... If all of these features depend on common local storage layer, how are you going to develop them truly in parallel?
Once you've defined the dependencies, you will be able to decide in what degree the features can be developed in parallel. Do different teams need to agree on common interfaces? Could a feature be completed even if other teams are still at 0?
3. Build variants are your friend
different "testing" APK versions shouldn't contain ANY of the code and
resources (so no shared strings and images) from other APK versions
(for security/reverse engineering reasons cause different people will
have access to different APK versions)
Flavors are meant to do exactly what you're looking for, that is, build different apks from the same project but using different subsets of code and/or resources.
Keep in mind that you can have flavors in multiple dimensions (and build types). For instance, you could have one flavor dimension called "network", with 2 flavors "mockedNetwork" and "actualNetwork". Then you could have another dimension "feature", with "featureA", "featureB", "featureC". You could then easily build and release 6 types (well 12 if you have also debug and release build types) of apks, one for each combination (mockedNetworkFeatureA, actualNetworkFeatureA, mockedNetworkFeatureB etc.).
With flavors you could easily replace chunks of the app that you don't want your tester to have. For instance, you could have a strings.xml file with only lorem ipsum strings and then keep actual texts strings only for internal use.
What I would do is to use git. The master branch is kept clean for production and each team can have one or multiple branches to work on. They can change the package name in their branch so your APKs will all be different. The only problem with this approach will be the merges into the master branch that might cause conflicts. But this could be a solution to your problem.
I am working on an Android app that has several different product flavors. Each flavor has a unique set of libraries it needs, but I don't have this information until runtime. Right now, all the features of the app are packaged into each product flavor, even if that flavor only uses a handful of them. What I would like to do is, at startup, determine which features can be accessed, and download the appropriate libraries it will need. Is there a way that I can determine at first startup which Fragments can be accessed by the Activity?
I have an application A that consists of feature 1 , feature 2, feature 3. Now I want to create an application B that consists of only feature 1 and application C that consists only of feature 3.
Things I have tried
I have organized the packages according to features. Now maintaining Application A, B and C as separated projects will lead to duplication of efforts.
Android Studio
Using Android Studio I have created "Variants". I am able to get Application A, B and C as apks but size of all the apk is same i.e they contain all the code of complete project. I want Application A, B and C such that it only consists code relevant to there feature. Excluding packages while building is not supported as can be seen from this link. Am I missing something or is there any other way to customize build script for the applicatoin
Your best approach would be to separate your features (1-3) into standalone libraries that can be Java or Android library modules. In your Android Studio project, you can have more modules for applications A-C, and have them depend on the feature modules they need.
Maintaining the features as standalone libraries and keeping the different apps separated from them will probably make your code more modular and easier to maintain, so it should help you in that regard as well.
Using flavors in Android Studio to differentiate the application types would make sense if the applications are very similar and will share the majority of their code. Examples would be a free vs. paid version of the same app. If the apps are conceptually different, you'll probably find it better to make them separate app modules.
I just finished watching Xavier Ducrohet presentation about gradle, and I am about to start using flavors. I want to understand what are their big advantage over libraries?
I know that android library can have it's own manifest / resources and of course sources, and so does flavors. But what else is there? Why should I use them?
Flavors and libraries aren't really comparable.
A library is typically a discrete piece of functionality that you can reuse across multiple projects. It might provide a piece of functionality that you use frequently or it might provide a custom View that you find yourself using in a lot of applications.
Product flavors are slightly different versions of the same application. The most common example is a paid vs. free app- with product flavors you can have a single codebase that generates both versions. Another more simplified example would be an app that is available in two colors- you might have a red product flavor and a blue product flavor. In this case the only difference might be a single color string in your resources.
Where I think the confusion is coming from is that you can use a library to accomplish the goals of the product flavor system. That is, you can take your common functionality and place it in a library project that you include in each of the versions of your application. This is a messy way to accomplish the goal of having two apps with only minor variation between them, and if this is your goal, you should use product flavors instead.
From the Gradle Plugin User Guide:
If the answer to βIs this the same application?β is yes, then this is probably the way to go over Library Projects.
Since it's popular to have both a free and a paid version in the android market of the same app, I had decided to do the same. Initially I just duplicated the complete codebase and adapted some code here and there (added ads, built in some limitations etc) since there was no option to do library projects at that time, but that left me with two projects that are horrific to manage fixes to bugs as I need to do those twice.
Since r14 we can use library projects with resources, so that would be a great solution to this particular problem as far as I can tell. Therefore I've read up on library projects and conciderations, and I'm curious to know what the minimum amount of files needed in the projects of the different versions are. My questions therefore are;
Could I have all of the code in the shared project, and have bare bone project with basically just a manifest?
If so, should I? is this the optimal way conceptually? (so apart from the fact that it depends on my code base)
How should I deal with library package naming, are there specific rules?
Are there tools about that can compare code from two different projects and perhaps merge them auto-magically or auto-manually, and which one is preferred?
If I understand your problem correctly, you want to create multiple Android apps that are similar to one another (i.e., have a lot of the same source code), but which are different in particular (minor) ways, and you want each of these apps to have a distinct package, so that it can be separately uploaded and distributed on an app store such as Google Play. A Project Library is an excellent facility for accomplishing those goals.
I'm assuming that the differences between your various versions are minor, involving things like resources and the app name and package, and a switch that turns on certain features for a paid version while leaving them off for a free version.
Even if that is not the case, by using polymorphism in the ways described below, your various apps could differ in significant ways and still share a common Project Library.
A Project Library can be defined in Eclipse in the same way as any Android project can be defined, but it is marked as a Project Library (by checking the "Is Library" box near the bottom of the Android page of the library's Project Properties dialog) and cannot be compiled and run on its own. Instead, it is intended to be included by reference in one or more other projects which are actual apps (by adding a reference to it on the Android page of each such app's Project Properties dialog). These apps will use the Project Library, and thus will share its code and capabilities.
Each such referencing app will have its own manifest file (where their respective, different packages can be declared), and they can also define their own classes (including classes derived from the Activity and/or Application classes of the Project Library), so that these classes can be specialized polymorphically for each app that uses the Project Library (e.g., by overriding methods or by providing definitions for methods that are defined as abstract within the Project Library's Activity- or Application-derived classes), although you can also use those Library classes without modification (provided that they are not abstract) by simply referencing them within the manifest file (e.g., in an activity or application tag) of each app that uses the Library, just as you would reference Activity or Application-derived classes defined within the app itself.
If you decided to use this approach, then you would put your main source files in a Project Library, and would create a separate project for each app you want to produce, each of which would reference the Project Library. The manifest file of the Project Library would be overridden by the manifest of whatever project is being created using that Library (actually, I think that the Project Library's own manifest is completely ignored, not just overridden, but nonetheless it is useful to create a manifest for the Library, so that you can manually template - copy and edit - the manifest of each project that uses it from the Library's own manifest).
I have used this approach to create multiple android apps that share some of the same capabilities, and it has worked very well for me.
Regarding package naming, any old package name will work for a library project, but of course it makes sense to use the same prefix for the Library Project's package as you use for your various individual (e.g., free vs. paid) apps that use it, with something like ".library" as the last part of the name, while the various apps could have endings like ".myappfree" and ".myapppaid". Naturally, you would want to use your reverse domain name convention for the library's package prefix to prevent conflicts, just as you would for a package name of a released app.
In Windows, a nice, open-source tool for comparing code bases is WinMerge:
http://winmerge.org/
If I were in your position, however, I would only use this tool to manually identify differences, and would not attempt to use it to automate the refactoring of your code into a Library Project. That would be best done under your own (manual) control.
Finally, as an alternative, you might consider using a single app that is free and that has your free app's capabilities by default, with an option to upgrade to your full app's capabilities (delivered within the same APK) via an in-app payment, rather than having separate free and paid apps. In-app payments have improved a great deal in the past several months (with the release of version 3 of IAB), and although there are still some glitches, they have become a more practical alternative to the free/full dichotomy than they were at first.
Yes, you can have a project that is basically just a manifest specifying app name, name space, icon etc, with all the actual code and 99% of the resources in the library project.
Yes, I think you should use this approach. It's very common to use library projects to deal with the Free/Paid app problem.
I've not had any problems with naming, though you should be careful with any resources in separate projects to avoid using the same names.
I'm not aware of any tools, and if it were me I'd want to do it manually to be sure I'm merging what needs merging and keeping separate what needs to be separate. you've one significant refactor to do, but once all the duplication is removed I'm sure it'll be much easier.