Debugging is the process of finding and resolving bugs or defects that prevent correct operation of computer software (Wikipedia).
Nowadays debugging is not an easy task, specially with all the complexity around current systems:Android is not an exception to this rule and since we are dealing with asynchronous executions, that becomes way harder.
As you might know, at @SoundCloud, we are heavily using RxJava as one of our core components for Android Development, so in this article I am gonna walk you through the way we debug RxObservables and Subscribers.
Give a warm welcome to Frodo
Let me get started by introducing Frodo, but first, if you already watched Matthias Käppler talk at GOTO Conference (if you haven’t yet, I strongly recommend it), you may have noticed that he talks about someone called Gandalf (minute 41:15). All right, I have to say that in the beginning, Gandalf was my failed attempt to create an Aspect Oriented Library for Android, fortunately after working hard and receiving useful feedback, it became an Android Development Kit we use at @SoundCloud. However, I wanted to have something smaller that solves only one problem, so I decided to extractRxJava Logging specifics that I have been working on, and give life to Frodo.
Frodo is no more than an Android Library for Logging RxJava Observables and Subscribers (for now), let’s say Gandalf’s little son or brother. It was actually inspired by Jake Wharton’s Hugo Library.
Debugging RxJava
First of all, I assume that you have basic knowledge about RxJava and its core components:Observables and Subscribers.
Debugging is a cross cutting concern and we know how frustrating and painful could be. Additionally, many times you have to write code (that is not part of your business logic) in order todebug stuff, which make things even more complicated, specially when it comes to asynchronous code execution.
Frodo was born to achieve this and avoid writing code for debugging RxJava objects. It is based on Java Annotations and relies on a Gradle Plugin that detects when the Debug build type of your application is compiled, and weaves code, which is gonna print RxJava Objects logging informationon the android logcat output. For instance, it is safe to keep Frodo annotations in your codebaseeven when you are generating Release versions of your Android App. So now, let’s get our hands dirty and have a taste of it.
Using Frodo
To use Frodo the first thing we need to do is to simply apply a Gradle Plugin to our Android Project like this:
As you can see, we add “com.fernandocejas.frodo:frodo-plugin:0.8.1” to the classpath and afterwards we apply the plugin ‘com.fernandocejas.frodo’.
That should be enough to have access to the Java annotations provided by the Library.
Inspecting @RxLogObservable
The first core functionality of Frodo is to log RxJava Observables through @RxLogObservable Java annotation. Let’s say we have a method that returns an Observable which will emit a list of some sort of DummyClass:
Then we subscribe to our sample observable:
When compiling and running our application, this is the information we are gonna see on the logcat:
Basically this means that we subscribed to an Observable returned by the list() method in ObservableSample class. Then we get information about the emitted items, schedulers and events triggered by the annotated Observable.
Inspecting @RxLogSubscriber
Let’s now explore what @RxLogSubscriber is capable of.
To put an example, let’s create a RxJava dummy Subscriber and annotate it with @RxLogSubscriber.
Forget about the backpressure name of this Subscriber for now, since this topic deserves a whole article. Just know that this Subscriber will only request 16 elements and it is gonna do nothing with the items it receives on the onNext() method. Even though that, we still wanna see what is going on when it subscribes to any Observable which emits Integer values:
Here is when we subscribe to our SampleObservable:
Again when we compile and run our application, this is what we get from the logcat output:
Information here includes each of the items received, number of elements, schedulers, execution time and events triggered.
As you can see this information is useful in cases of backpressure, or to see in which thread the items are being emitted or when we wanna se if our Subscriber has subscribed successfully, thus avoiding memory leaks for example.
Frodo under the hood
In this article, I’m not gonna explain in details how the library internally works, however, if you are curious about it, you can check an article I wrote last year which includes an example with the same approach I am using for Frodo.
You can also look into a presentation I prepared as an introduction for both AOP and the Library or even better, dive into the source code.
Disclaimer: Early stage
Frodo was just born and there is a long way ahead of it. It is still in a very early stage, so you might find issues or things to improve.
Actually, one of the main reasons why it was open source, was to receive feedback/input from the community in order to improve it, make it better and more useful. I have to say that I’m very excited and I have already used it in 3 different projects without many problems (check the known issues section below for more information). Of course pull requests are very welcome too.
Known issues
So far, there is a well known issue: since Frodo relies on a Gradle Plugin (as explained earlier) to detect Android Debug build variant and weave code, if you make use of Android Library Projects,when you build your Application (even the debug build type), the official Android Gradle Plugin will always generate release versions of all the Android Library projects included in your solution, thus,this stops Frodo from injecting generated code in annotated methods/classes. Of course this is not gonna make your app to crash but you won’t see any output on the logcat. There is a workaround for this but be careful if you use it, since you do not wanna ship a release version of your app with business objects being logged all over the place and exposing critical information.
Just add this flag to the android section in the build.gradle file of you Android Library Project:
Frodo Example Application
The repository includes a sample app where you can see different use cases, such as Observable errors and other logging information. I have also enabled Frodo in my Android Clean Architecture repo if you wanna have a look into it.
Wrapping up
This is pretty much I have to offer in this article, and I hope you have found Frodo useful.
The first version is out and you can find the repository of the project here:
https://github.com/android10/frodo
As always, any feedback is welcome. PRs as well if you wanna contribute. See you soon.