Set up your Android project for success

Successful Android development

Having developed Android apps for startups as well as Fortune 500 companies for many years, we at ElevateX strongly believe that every successful Android app should have the following high-level design goals: 
 

  • Pleasant user experience with a modern, fluent, and responsive UI
  • Offline support for spotty networks in e.g. subways
  • Maintainable, clean code base with high test coverage
  • Ability to A/B test the UI for rapid prototyping
  • Ability to release the app continuously to different user groups
  • Push-Notification- and App-Deep-Link-support to re-engage users

We rarely get the chance to start an app from scratch but don’t let this be an excuse to stick with outdated libraries, frameworks, practices, and untested code. Instead, consider applying our recommendations to your current project when e.g. implementing new features or new sections of your app. Thereby, you can keep your legacy code unchanged while slowly but surely improving your overall app quality.

In the following, we outline the Android project set up we aim for today – in February 2019. 

We start out with (1) some Android project basics, followed by (2) infrastructure recommendations that go beyond just writing maintainable source code. Then, (3) we outline some app architecture decisions that worked well for us in past projects and enabled (4) automated testing. To achieve all this more easily there are (5) some handy libraries and tools. We finish with (6) some additional tips. 

1. Basic Android project setup

  • Use the latest Gradle build tool and its dependency management
  • Setup build flavors for e.g. development and production environments
  • The minimum API level is likely defined by the customer but should be no smaller than Android 5 (Level 21)
    • Use the Android Support Library AndroidX to bridge the gaps between API levels – make sure to adapt to AndroidX and not use the deprecated, version-specific libraries.
  • Prefer Kotlin over Java
  • Use Lint tools to flag potential programming errors, bugs, code style, etc.

2. Infrastructure

  • Use Git version control with master, develop, and feature branches. Tag releases and enforce merge between branches only via a pull request (PR)
  • Use Continuous Integration (CI) – e.g. set up Jenkins to build and run (unit) tests on every commit. At least the nightly build must run integration tests, too.
    • Optionally, SonarQube could be set up to find code smells and enforce test coverage in the form of a quality gate for every release.
  • Require PR review by at least one other developer and allow to merge branches only if the CI build of that branch is passing and marked “green”
  • Setup AppCenter (formerly HockeyApp) to be able to release app versions and flavors to custom distribution groups (e.g. developers, testers, clients, beta users, …)
    • AppCenter also comes with crash reports and analytics, which will help with fixing bugs reported by users

3. Android Architecture

  • Use the Model-View-ViewModel (MVVM) Architecture Pattern as it nicely separates concerns and enables unit testing of the business logic of the app
    • The Context or other Android resources are never to be used in models nor in view models to enforce their 100% unit testability
    • Introduce “Services” that provide the functionality to ViewModels like receiving and persisting data etc.
    • Introduce Navigator(s) to centralize navigation between views using intents (don’t pass massive data as Parcelable but rather use ids to locally stored information)
    • Alternatively, the Model-View-Intent (MVI) pattern could be used as it nicely enforces immutable data/objects with a uni-directional data flow by design
  • “Package by feature” enforces separation of concerns and enables potential use of Android Instant App
    • Introduce a shared module for data models and common functionalities (e.g. date parsing)
  • Respect the Android life cycle at all times and use the lifecycle-aware components of Android Jetpack.
  • Create custom views to encapsulate common views – e.g. a customer-specific date picker
  • Use dependency injection and generate the dependency graph automatically
    • This enables better testability as mock objects can be used
  • Use RxJava
    • As Android Apps are highly driven by asynchronous events and an app can be interrupted by the system at any time, RxJava has proven to be a key asset (more information below)
  • Use Androids’ shared preferences, file storage, and SQLite database to persist data locally
  • Use Android resource files to define themes, dimensions, images, strings, etc. and use respective subfolders for localization purposes and build flavor differences

4. Testing

  • Use Junit as much a possible – it is fast and unit-testable code is a good indicator of good separation of concerns within the app
    • AssertJ for easier assertions 
    • Mockito to create mock objects of dependencies
    • the Arrange, Act, Assert structure within tests
  • Use Espresso for UI and integration testing
    • Add at least one test that checks if the app main screen is shown after app launch
  • Monkey runner can be used to stress-test the app

5. Android Libraries / External tools

  • For dependency injection we recommend Koin for pure Kotlin projects, Dagger2 alternatively
    • Define at least a global app scope and an activity-specific scope – add more specific scopes if needed
  • Room  – Android Jetpack’s persistence library – is the preferred way to harness the full power of SQLite
  • The Gson library is suited perfectly for JSON conversion.
  • Retrofit to perform REST (backend) calls – it uses Okhttp under the hood
    • Set up Okhttp to cache backend responses and downloaded images
  • Glide image library
    • Use cache and image transformations when displaying images for UI performance reasons and do not waste the user’s mobile data
  • RxJava 2 
    • Data flow can be modeled very nicely and asynchronous by design – events/data can be chained, filtered, composed, etc., threading can be explicitly defined, and observers can subscribe to events of interest
    • Introduce some RxBinderUtil that keeps track of subscriptions and is life cycle aware so it can dismiss active subscriptions in case of respective Android life cycle events
  • We advise to not use data binding as the benefits don’t justify increased build time and other drawbacks. With the introduction of Kotlin views can access UI elements by their id without using findViewById.

6. Miscellaneous

  • UI performance
    • Use RecyclerView for any sort of lists
    • Avoid deep nesting in layout files and use the Constraint Layout instead
  • Analytics
    • It is already part of AppCenter but it might be useful to introduce e.g. Google Analytics for remarketing via Google Ad Words. Please keep GDPR restrictions in mind. The user needs to explicitly consent to tracking of this kind. This also applies to the usage of Facebook SDK integrations for re-marketing or Single sign-on reasons.
  • For push notifications, we recommend Firebase messaging (also available for iOS)
  • Authentication
    • Make use of Retrofit’s authentication interceptors to handle e.g. OAuth authentication
    • For a pleasant user experience, allow the user to use Single sign-on via Google, Facebook, etc.
  • Permission management
    • Since the user explicitly needs to grant permissions to the app to e.g. access his location, the core use cases should not require any of these platform features – it should be a nice-to-have for improved user experience

Conclusion

Aiming for this kind of project setup helped us deliver outstanding apps for our clients and we are more than happy to share our learnings with you. What’s the biggest takeaway for you? Please provide feedback and drop us an email at android@elevatex.de.

To learn more about Android development, check out our blog post about resources every Android developer should follow.

Read the latest stories.

Never miss an update from us. 
Follow us on LinkedIn or subscribe.

Explore More

Prompt Engineering

What Is Prompt Engineering? – Insights Into the Jobs Of Tomorrow

A career in Prompt Engineering seems promising given the increasing growth of artificial intelligence (AI) in various industries. Tech companies from around the world are seeking qualified and efficient Prompt Engineers. Not only do they have the opportunity to further develop their skills, but they can also earn a substantial salary from it. What Is

Read More »
Versicherungen für Selbstständige

Insurance For Self-Employed – What to Know as a Freelancer

There are the same insurances for self-employed as for employees. The difference, however, is the responsibility you bear for your insurance coverage as a self-employed person. Self-employed people have to insure themselves against risks during their work, as you do not have an employer to cover the financial consequences of any damage. Therefore, ensuring that

Read More »
Confidentiality Agreement

Confidentiality Agreement – What Freelancers Have to Know

In many freelance projects in the IT environment and other areas, the contracting parties exchange information that is confidential. This can be about the projects themselves, but also about technical and content issues. The freelancer is not bound by the confidentiality regulations in the fulfillment of his assignment, which arise from the employment contract in

Read More »
Freelancer Contract

Freelancer Contract – The Ultimate Guide to Contract Creation

Especially in the IT sector, but also in other project fields with creative demands, employees are not always employed on a salaried basis. For project-related work, the freelancer contract is the best option. On its basis, you are dealing with a contract for work or services, but you are not working as an employee. Especially

Read More »
Internal and External Recruiting

Internal and External Recruiting Methods – Direct Comparison

The shortage of skilled workers and labor has made recruiting a critical process for success for all companies. Both internal and external recruitment serve as instruments for filling the company’s own vacancies. However, there are specific advantages and disadvantages to be considered for both options. These ensure that not all tools of both external and

Read More »
Job Interview

Crush any Job Interview: Top 9 Questions with Foolproof Answers

The new employer was already able to get an idea of your professional skills in your application. At the interview, they want to get to know you better and find out whether you fit the advertised position, the team and the company itself. Various questioning techniques are used in job interviews. HR managers use different

Read More »

IT Experts Are Highly-Demanded.
Future-Proof Your Team.