How to customize mutliple app in Android Studio? - java

I have a project in Android Studio and two different app module but both of them are using this same Android library (core code). I want change some resources and logic in application but this code is in core (Android library). How do I approach this? How to customize core code?

I've been asking the same question and after some research, I've found that you have different approach:
Gradle Flavors:
Why Product Flavors?
They address the issue of having separate project code for each version of the app while still having one project code.
Given a scenario where you have a free and a paid app you can limit features in the free and expose all the other features in the paid version of the app.
Given another scenario where you want to implement region-specific functions depending on the country, you can use product flavors for such a use case.
White labeling (these are apps that are developed by a certain company, and they are re-branded and resold by other companies).
Pros
They address the issue of having a separate project code base for each version of the app.
They keep the code tidy and makes it much easier and faster to navigate through the code base as everything related to the specific product flavor would be kept in their corresponding folders.
Cons
(Scaling Up) The more variants, the greater the complexity which thereby makes it harder to maintain the codebase.
-IDEs sometimes takes time to build the project after switching between variants.
Source: https://levelup.gitconnected.com/simple-guide-to-android-product-flavors-674106455038
Multi-Module
Why ?
Faster build times.
Fine-grained dependency control.
Improve reusability across other apps.
Improves the ownership & the quality of the codebase.
Stricter boundaries when compared to packages.
Pros
Scales well as the application grows with new features
Medium to large development teams are able to work on different modules without affecting each other (Merge Conflicts)
Encapsulates unit and ui tests to their specific features
Keeps Resources separated between modules. Which improves readability and organization
Keeps logic contained in their own modules, which can be hidden behind interfaces
Forces the developer to keep their code better organized and structured
Improved build speed, as changes in a module means only that module will need to be rebuilt
Cons
Adds additional boilerplate around the construction of the modules
More development time overall
Requires a maven/gradle file for each module
Navigation between module activities can be difficult to setup correctly
Requires a lot more pre-planning on how best to structure code, and determining where shared code bases are stored.
Limited amount of online resources showing best practices
Source:
https://medium.com/swlh/modularization-by-feature-and-layer-with-android-architecture-components-80bf317d737
https://codelift.dev/android-modular-app-architecture/
Also look at the gradle doc to start with modularizing.

You can build the library's aar and use it in your main projects by simply copying into lib folder in your project directory.
Or you can build it with services like Jitpack and add it to your project by the implementation method in Gradle.

Related

Android project library management pattern?

I have very general question about managing android library project and I feel it might have pretty simple solution. The library might be used as a base program for other projects, like framework but It could be better described as a group of functionalities that are the same - just to save time.
Lets say we have project where we decide to distinguish base part which is exported as library.
Those library contains activities, network utilities, some preferences and database schema(!).
Is there any pattern how to do this, is it a good idea to do this with database too?
I mean actually I've got the library but almost every method that is dependent from other one has to be overridden what causes to override almost everything.
Maybe the system should be designed with specific cohesion strategy?
Thanks

How to organize larger Java projects - Projects vs. Namespacing?

I'm wondering if there is some recommended reading, best practice or opinion on how to organize larger Java projects.
I made the observations that there are folks who split up everything into projects (i.e. modules) and create many many projects that share a web of dependencies. This has the advantage that compilation is often super fast, but when the project gets large nobody knows anymore what depends on what and why. Not talking about dependent libraries, version conflicts & co.
The alternative is to have just a couple of projects such as frontend, backend, ... . The namespacing does the job.
Any opinion, further reading anyone could recommend?
As soon as you start splitting a big project up into smaller projects, you encounter a lot of dependency tracking that you generally didn't have to consider. You could manage this yourself or you could use software which already handles a lot of the core issues.
I would recommend Apache's Ivy. It integrates well with Apache's Ant, and has a separate configuration file (which gets checked in) to track what is required for each kind of build.
Apache's Maven is another good choice; however, it does a lot more than Apache's Ivy. Sometimes that "a lot more" means you doing less of what you would have done anyway, sometimes that "a lot more" means you are doing (and configuring) things that you didn't do before. Depending on the fit of your practice to Maven's, migrating to Maven might be easy or very hard.
In addition, using Ivy, you can set up your own private repository of "permitted" jar files to pull from, and that will make code auditing much easier. Basically, reconfigure ivy to not pull from the web, but to pull from your local repository only, and then control access to the repository to only allow jar files which were reviewed to have acceptable licensing.
Once you have software in place, you can afford to split projects up into smaller pieces. This will permit you to do the right thing (if your project favors small decomposition) instead of the expedient thing (a few big chunks which might not really buy you much in decomposition maintainability). As far as where to make the cuts, that depends heavily on the specifics of your application.
Many small pieces tend to be easier for a new person to digest one-by-one. They also get people thinking about where functionality is to be added to a project; however, it does cost time and effort to untangle and separate all of the components. The plus side is that it is generally easier to test and validate something smaller, the downside is that it is a longer road to decompose one monolithic collection of responsibilities into many small, well integrated yet functionally disparate units.
Good luck
A very large project will need to have some way of tracking all of the libraries and other dependencies that it uses. The defacto standard for doing this is Maven. It's definitely the best way to start keeping track of what is going into your application.
Then you can decide how to split your application up. Basically, what you're trying to do here is to split up your application up into complete functional pieces. For instance, if you had a website that had a contact form, a photo gallery, a shopping cart, and a forum, you would split the project up into pieces that contained each of those different modules.
Actually, you will want to utilize both projects and namespacing.
Namespacing is an important tool for differentiating what purpose a code has at the code level. Regardless of what project a class comes from, the package should give me some idea of its purpose.
At a higher level, it is easier to manage builds and your development environment by having your code separated into projects. For instance, if you are developing a UI, why do you need to have the database code loaded into you IDE? It is just extra clutter in your workspace. It also makes it simpler to share common functionality between different projects. This will of course lead to needing some form of dependency management, of which either of the mentioned tools such as Maven or Ivy will suffice.
An important note though. Do not use split packages between projects. This causes nightmares if you or anyone who will ever use your code wants to do so in an OSGi environment. So, your namespaces should be unique within a project, although they should share a common root with other related projects.

Should I be concerned with large number of dependencies?

I was just about to include the HtmlUnit library in a project. I unpacked the zip-file and realised that it had no less than 12 dependencies.
I've always been concerned when it comes to introducing dependencies. I suppose I have to ship all these dependencies together with the application (8.7 mb in this particular case). Should I bother checking for, say, security updates for these libraries? Finally (and most importantly, actually what I'm most concerned about): What if I want to include another library which depends on the same libraries as this library, but with different versions? That is, what if for instance HtmlUnit depends on one version of xalan and another library I need, depends on a different version of xalan?
The task HtmlUnit solves for me could be solved "manually" but that would probably not be as elegant.
Should I be concerned about this? What are the best practices in situations like these?
Edit: I'm interested in the general situation, not particularly involving HtmlUnit. I just used it here as an example as that was my current concern.
Handle your dependencies with care. They can bring you much speed, but can be a pain to maintain down the road. Here are my thoughts:
Use some software to maintain your dependencies. Maven is what I would use for Java to do this. Without it you will very soon loose track of your dependencies.
Remember that the various libraries have different licenses. It is not granted that a given license works for your setting. I work for a software house and we cannot use GPL based libraries in any of the software we ship, as the software we sell are closed source. Similarly we should avoid LGPL as well if we can (This is due to some intricate lawyer reasoning, don't ask me why)
For unit testing I'd say go all out. It is not the end of the world if you have to rewrite your tests in the future. It might even be then that that part of the software is either extremely stable or maybe not even maintained no more. Loosing those is not that big of a deal as you already had a huge gain of gaining speed when you got it.
Some libraries are harder to replace later than others. Some are like a marriage that should last the life of the software, but some other are just tools that are easily replaceable. (Think Spring versus an xml library)
Check out how the community support older versions of the library. Are they supporting older versions? What happens when life continues and you are stuck at a version? Is there an active community or do you have the skill to maintain it yourself?
For how long are your software supposed to last? Is it one year, five year, ten year or beyond? If the software has short time span, then you can use more to get where you are going as it is not that important to be able to keep up with upgrading your libraries.
It could be a serious issue if there isn't a active community which does maintain the libraries on long term. It is ok to use libraries, but to be honest you should care to get the sources and put them into your VCS.
Should I bother checking for, say, security updates for these libraries?
In general, it is probably a good idea to do this. But then so should everyone upstream and downstream of you.
In your particular case, we are talking about test code. If potential security flaws in libraries used only in testing are significant, your downstream users are doing something strange ...
Finally (and most importantly, actually what I'm most concerned about): What if I want to include another library which depends on the same libraries as this library, but with different versions? That is, what if for instance HtmlUnit depends on one version of xalan and another library I need, depends on a different version of xalan?
Ah yes. Assuming that you are building your own classpaths, etc by hand, you need to make a decision about which version of the dependent libraries you should use. It is usually safe to just pick the most recent of the versions used. But if the older version is not backwards incompatible with the new (for your use case) then you've got a problem.
Should I be concerned about this?
IMO, for your particular example (where we are talking about test code), no.
What are the best practices in situations like these?
Use Maven! It explicitly exposes the dependencies to the folks who download your code, making it possible for them to deal with the issue. It also tells you when you've got dependency version conflicts and provides a simple "exclude" mechanism for dealing with it.
Maven also removes the need to create distributions. You publish just your artifacts with references to their dependents. The Maven command then downloads the dependent artifacts from wherever they have been published.
EDIT
Obviously, if you are using HtmlUnit for production code (rather than just tests), then you need to pay more attention to security issues.
A similar thing has happened to me actually.
Two of my dependencies had the same 'transitive' dependency but a different version.
My favorite solution is to avoid "dependency creep" by not including too many dependencies. So, the simplest solution would be to remove the one I need less, or the one I could replace with a simple Util class, etc.
Too bad, it's not always that simple. In unfortunate cases where you actually need both libraries, it is possible to try to sync their versions, i.e. downgrade one of them so that dependency versions match.
In my particular case, I manually edited one of the jars, deleted the older dependency from it, and hoped it would still work with new version loaded from other jar. Luckily, it did (i.e. maintainers of the transitive dependency didn't remove any classes or methods that library used).
Was it ugly - Yes (Yuck!), but it worked.
I try to avoid introducing frivolous dependencies, because it is possible to run into conflicts.
One interesting technique I have seen used to avoid conflicts: renaming a library's package (if its license allows you to -- most BSD-style licenses do.) My favorite example of this is what Sun did when they built Xerces into the JRE as the de-facto JAXP XML parser: they renamed the whole of Xerces from org.apache.xerces to com.sun.org.apache.xerces.internal. Is this technique drastic, time consuming, and hard to maintain? Yes. But it gets the job done, and I think it is an important possible alternative to keep in mind.
Another possibility is -- license terms abided -- copying/renaming single classes or even single methods out of a library.
HtmlUnit can do a lot, though. If you are really using a large portion of its functionality on a lot of varied input data, it would be hard to make a case for spending the large amount of time it would take to re-write the functionality from scratch, or repackage it.
As for the security concerns -- you might weigh the chances of a widely used library having problems, vs. the likelihood of your hand-written less-tested code having some security flaw. Ultimately you are responsible for the security of your programs, though -- so do what you feel you must.

Separate Subversion branches per programming language?

In some projects, I have to deal with more than one programming language (for example a Delphi GUI application which communicates with an C# or Java app). The Subversion repository currently contains three top branches, one per language.
Should I change this and group all parts of the project in the trunk like in the following example to make branching and tagging on project level easier?
project1
branches
...
tags
...
trunk
csharp_app
delphi_app
java_app
...
project2
...
As these separate sub projects interact, then they need to move in lockstep, and you need to tag/branch/release the C#/Java/whatever components together. If they're unrelated then I would advocate (perhaps) separate repositories, or separate directories within the same repository. But not branches or tags.
Branches are used to manage different development streams on the same codebase. Tags are used to indicate a particular point in the project's evolution.
I think the programming language is irrelevant. Ask yourself what your releasable is, and how you need to manage this. I've done this successfully in the past with projects incorporating Java and C++, and the language is not the issue - it's keeping the components in sync that you need to manage.
I wouldn't necessarily create a new top-level directory per language. What happens if your Java component suddenly requires a JNI layer ? It strikes me that the implementation is reflected in the top-level directory structure, and that shouldn't really be a concern.
Programming language is irrelevant when you're managing a single project. A single module may be written in a variety of programming languages but still be too tightly coupled to worth separating. If each module of the application (whether or not it's written in the same language) is independent enough to be considered a separate project (and consequently, become independently versioned), you may want to separate it. Otherwise, don't do that.
I don't think it's a good idea, because theoretically the different components could break compatibility, and if they don't stay synced up it would be hard to go back to the last working good config.
Yes. The criterion is whether the apps require some form of synchronization of their features between each other, and that communication protocol (API, shared code, shared libs) may change over time. If the apps have nothing to do with each other, then separate repositories. Having apps written in multiple languages in the repository is irrelevant.

Java release engineering good practices [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I've got a fairly simple open-source Java project I am starting. This process is new to me, I'm used to writing programs just for myself. What are some good practices to be aware of when releasing open-source projects in Java?
Here are some things I can think of, can you suggest others?
version control repository (what do you use to explain relevant tags/branches? an external README file?)
include appropriate open-source license in code
include prepackaged executable JAR file, including version number in the filename
some kind of README file that explains external dependencies needed to build/run the software (is there a common convention for what filename and where to put it?)
a webpage for the project, w/ a link to it in the source code and/or executable, in case someone obtains the source code or executable first (rather than through the webpage in question)
One thing you should definitely do (because it's Java) is to generate Javadocs for your code. This means commenting classes and methods using the Javadoc notation for easier readability to others.
You could also use Maven for releasing your code. With it it's quite easy to create a site for your project, specify the dependencies, optimize the releases...For example, the Commons projects at Apache use Maven.
Basically you want your project to work 'out of the box'. When people are choosing the right open source project for a task, they download a bunch of projects that say they support the task, and use the best one. If a project needs significant work to setup (e.g. downloading 20 JAR dependencies from 20 different sites) most people will only either try it as a last resort or just ignore it.
Repository: You might try some newer repository engine - like Mercurial or Git. They ease development and ease merging of branches. Importantly though, choose an engine that is supported natively by your IDE.
Dependencies: You should use a readme to state dependencies, but this is not sufficient, either use Maven to manage dependencies, in which case you just need to include pom.xml file, or include JARs that you are dependent on in your distribution. In second case divide dependencies into mandatory, optional, compiletime and test. An example of an optional dependency are the bytecode generation tools for Hibernate.
Site: Maven may create a site that is associated with particular version of your software (never used that though).
Documenation - JavaDoc: Document everything, and try to enforce a policy that ensures high quality javadocs:
/**
* Sets the cost
* #param decimal cost
*/
public void setCost(BigDecimal decimal){
is useless. Better is:
/**
* Sets the cost, cost is in currency setted by #setCurrency.
* #param decimal cost, precision shoule be at least three places
*/
public void setCost(BigDecimal decimal){
Documentation: Javadoc is not enough. Give some starting point - a tutorial is preferable (and I don't mean the kind of tutorial with many screenshots of eclipse dialogs ;)). Example code is OK too, or at least write somewhere - 'Reading the javadoc of the EntryPoint class is a good way to start using this library'. If you have only javadocs anyone who is considering using your library will be presented a list of all the clases and packages, and will not know where to start.
Bugtracking Software: You won't remember more that three bugs at a time (and will forget things) - also it will help you manage tasks, and new wanted features.
You may want to try:
FogBugz - its nice, but costs money. (Free for up to two developers).
Bugzilla - nice, popular and free
Project Management Software: This will help you to calculate release dates, split tasks between developers etc.
dotProject - free and OK.
FogBugz - again works great.
Try to pass Joel test
Build process: Make the build a one-click process. For example an ant script that increments the version number, launches maven builds, deploys the site and so on. Worth the effort!
Forum: A nice idea, will help support.
Wiki: In many (even quite developed) projects such wikis are rather empty which is bad (as it makes people think 'how can this be great software if no-one writes in this wiki').
Plan on developing some type of website. If your code involves web software, people really marvel if you are using it as part of your site.
Developers love good documentation and lots of samples. I have seen projects that have lots of powerful code but 0% documentation fall hard.
Having a wiki setup to let people write ideas and recipes is a definite plus. (I recommend mediawiki).
A forum to post ideas, threads of discussions, i.e. a community forum is also good.
Setup a mailing list and encourage people to join.
Post real updates to your mailing list, wiki site, and also as news on your main site to show you are really working on things. Encourage participation. Make yourself available. This all generates a sense that you are interesting in chipping in, and that you are open to input from others.
I suggest using MAVEN as tool for managing external dependencies needed to build/run
You can aslo use Vulcan or alike for continous inetgration, so it is known whetaher current version is realy working or not.
I know Maven is already mentioned, but I think that even more important than using Maven is to publish artifacts to Maven repositories, so that projects that do use Maven can use them.
Your project page can then provide direct links to a repo as well so it server as storage space for downloadables as well.
Also: in similar vein, making jars OSGi bundles -- which just means adding a few Manifest entries, nothing very complicated -- is another good thing.
Both of these help others to more easily add dependencies to your package (if applicable) and can help adoption.
Some more things to consider:
Sensible version number scheme (major version bump for incompatible changes; minor version for additions with backwards compatibility; or something like that)
Keeping good release notes
Use a bug-tracking system, if you can use one easily (Codehaus, dev.java.net, SourceForce etc all offer this)
Simple project Wiki for documentation
Mailing lists for discussion
Generate a ChangeLog from checkin comments. Separately create a release note explaining what you fixed/added in each release.

Categories