Skip links

Android Projects Like a Pro (Expert) – Part 1

Having a working Android App is not enough. More users, revenue and traffic need an engineering approach.

Have you recently managed to earn an Android Developer Certification? Or maybe just finished your first personal project? Being in charge of an Android app that has gained quite a market share? Or the team has just grown due to upcoming new features to make?

The next decisions and steps to take will have to tackle scalability and make you and your team Android Pros.

This guide is a summary of some tools and aspects the project will have to cover besides Fragments and Views.

Architecture

When an app becomes increasingly complex, with more features and aspects, making changes starts being problematic. Code duplication, newly introduced bugs, difficulty to change parts become common occurrences that hinder progress.

One of the steps for preparing for it, is establishing a good architecture, that takes into account modularity prospects of how much of a scope the project will have.

Is it a card game? Will you have to add different games afterwards? Is it a delivery app? What about adding pharmacies to it? How will you attach prescriptions? Is it a chat app? What about adding payments to it?

We may not predict the future but with some idea of the scope we will be able to think about how to modularize the project.

Also, architecture can take care of possible bugs and stability (for example, if we go the Google route, using their components that take care of configuration changes, stability issues, concurrency, etc), and make testing easier.

You can take a look at Google’s recommendation for apps architecture.

Not taking Google’s as a last word, you can also check out concepts and approach about MVP (Model-View-Presenter) by Netflix.

Modules

While “module” sounds like an abstract concept for separation of concerns or sub-units of code, in Android projects it can be the concrete concept of Modules. Those parts in which an Android Project can be composed of.

We may have one only module for the entire app (not bad if we are just starting and trying out an idea) but it will become more evident the need to divide the code.

Separation of concerns, from a functional or non-functional point of view can both work: We can separate layers (UI, Data, Network, etc), features (Auth, BigFeature1, BigFeature2, Commons, etc) or a mix.

In case of having multiple teams for different parts of the app (imagine a supermarket app where electronics appliances screens are totally different from the groceries ones), different modules may provide a natural separation among teams as well. This is useful as well in remote and distributed teams.

Here a bit more conceptual in-depth presentation about modules.

Demo Apps

The bigger the app, the more it will take to build, it is kind of a fact.

What if we want to (manually) test a part of the app we are working on? What if building takes 15 minutes? This WILL happen, sadly. In this case, modularizing among features may help as you may add mini-apps, maybe called “demos” or feature “Activities”, which will make it possible to have fast cycles for your features development.

In an Square talk they tell about one approach to have fast builds and development with this kind of architecture (video above).

Dependencies

It will become prevalent that different modules, will end up connecting, or said better, depending upon themselves.

Just imagine your “Auth” module being asked for sessions from multiple parts of the app. Dependency Injection will come to the rescue for this and for easier Testing as well.

You won’t see any big Android project without a kind of Dependency Injection applied to it. Currently on Android, Hint is taking the position from Dagger as the recommended standard to follow (pushed by Google).

Testing

Putting the religion aspect aside, more automated Testing will help the project. At least, avoiding to have the same bug twice.

The battery of tests will go from testing code/behavior one class at a time up to end to end tests that follow user paths in the app (for example, from login until saving changes in the app).

There is a Testing Pyramid that graphically explains three testing categories.

Android Testing Pyramid

Some things we’ll have to consider:

  • The need of implementing Dependency Injection in the project is inevitable. (At least, it will help with mocking features that are not meant to be tested in certain Unit Tests. It will also have a performance impact on Testing as well. Let’s avoid accessing the database or network when running a logic test.)
  • Small tests should be fast and generally only test Kotlin/Java code. Large tests, may need to run on real devices or emulation. That’s why some companies have phone farms or use services like AWS Device Farm or Firebase Test Lab.

The Fundamentals of Testing (for Android) can be seen here in the Android Developer site.

Another aspect of testing that appears is how much of our app we are testing. This can be reflected by Code Coverage. Nowadays Android Studio has a built-in feature that allows you to run code with code coverage. Use it at your own ‘risk’, do not try to reach 100% without a second thought. Some parts in the code will be much more critical than others, focus on them first.
Android Studio: how to run tests with code coverage.

Continuous Integration

How we can reduce the chances of delivering new bugs into production after making a new bunch of code (new features, fixes, etc)? What about having builds ready for QA? Or.. how will all those tests run when integrating code in our Master branch?

Here is when Continuous Integration takes their role in the project. Basically (but not restricted to) at least all new commits in our main branch (Master? but it could also be made for every feature branch) will trigger a new build. That build will itself be tested, both automatically and manually by our QA team (if we have any, please have one). It may also deliver those builds, making them accessible to anyone interested (QA, ourselves, Product management, etc).

Nowadays Jenkins CI is one of the most used, but some other tools can be used as well, Bitrise, Github Actions or even Gitlab CI.

In general it will be duty of one of the developers (or maybe a delivery manager?) to configure the platform and project with the steps to execute when integrating. Obviously we will want to run tests and make the build. Additionally many actions in this article series will end up running from CI as we want every “health” check for our project to be run automatically.

Check out this practical introduction to Android Continuous Integration.

There is more..

That’s all for this first part of the series. I promise, there is a lot more to cover when making Scalable Professional Android apps!

Leave a comment

Name*

Website

Comment