Skip to content

Instantly share code, notes, and snippets.

@amCap1712
Last active August 29, 2020 17:05
Show Gist options
  • Save amCap1712/0141cfd1ba4191e2b9787aaef2165044 to your computer and use it in GitHub Desktop.
Save amCap1712/0141cfd1ba4191e2b9787aaef2165044 to your computer and use it in GitHub Desktop.
The State of MusicBrainz Android

Project Requirements

A few months ago when the initial proposal was drawn, MusicBrainz for Android had a brittle interface. There was hardly any screen free of fatal errors and crashes. Hence, the proposal aimed at eliminating these instability issues. This included rearchitecting the application where necessary, adding tests and incorporating android best practices.

Repos

The entire work scoped across three repositories:

  1. MusicBrainz Android
  2. AcousticBrainz Android
  3. KTaglib

List of Commits

The list of commits is available during the span of GSoC period is available here.

Summary of Work Done

To begin with, the Repositories for fetching data from MusicBrainz server were refactored. Every screen had a different repository, hence, there was a lot of code duplication. This also meant that a feature had to be added at multiple places. The approach was essentially bug prone. For instance, the searching for artists produced a fatal whereas other searches worked well. The issue was solved using Java Generics. Now, there is a single LookupRepository which is utilised by all entities' ViewModels.

Next comes in dependency injection. Dependency Injection had a huge role to play in writing good unit tests. Dagger Hilt is awesome. Using a few lines of annotations, Hilt made it possible to switch from static methods to constructor injected components. Let's take the example of LookupRepository to understand the importance. As static methods went away, the LookupRepository class could extracted in form of an interface. The interface acts as a public contract. As long as the LookupRepository interface remains unchanged, the actual underlying implementation can be changed without affecting any other part of the app. This is great for testing as we can now just inject a test double to unit test the view models. The same example goes for Retrofit Service classes.

To further eliminate UI errors, ViewBinding was introduced. Its a really nice development tool. Whenever a breaking change is introduced in the UI files without making the required changes in the the associated Java/Kotlin code, the project fails to compile. This saves valuable developer time as the errors show themself at compile time with clear stack traces. No fuss of debugging a wrong findViewById call at runtime. Live Data Transformations have been heavily leveraged inside the app to follow best practices and avoid unnecessary usage of data from previous attempts.

Then come the actual tests, a good chunk of tests have been written around each component of the search and entiry pages. There are unit tests for each entity json to POJO conversion, fetchData calls to repository and entity ViewModels. The number of integration tests is however few and a work in progress. Furthermore, using CircleCI all commits and pull requests are tested to produce a valid apk and pass the unit tests.

Other than the scope of the project, it was realised that certain features from other Brainz projects should be incorporated in the app as well. As a matter of fact, the application now supports submitting listens. A lot of work has to be done in this regard though. Also, the capability of submitting acoustic data to AcousticBrainz work has been done on producing a mobile client for AcousticBrainz. The underlying library is ready for use but is on hold for now till some discrepancies with resolved with the upstream developers.

Challenges Faced

It has been a long road of development this summer. The biggest challenge I faced rearchitecting the application with a view to make it more maintainable and retain the code readability as well. However, the task I spent the most time on was getting instrumentation tests to run. After spending eight days on debugging, the bug fix turned out to be just 20 characters long. The issue was due inconsistent behaviour of the Android Gradle Plugin while building test and release applications.

Future Prospects

MusicBrainz Android is a living project with a lot of scope of improvements.

Support More tags in tagger feature.
Provide better listening support.
Increasing test coverage.
Write a better wrapper for chromaprint. Add support for remaining MusicBrainz entities. Display relevant data about MusicBrainz entities from AcousticBrainz and CritiqueBrainz.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment