RxDisposableWatcher
RxDisposableWatcher — find leaked subscriptions in RxJava code.
The Problem
Consider the following RxJava code:
class Thermometer {
fun observeTemperature(): Observable<Int>
}
// ...
val thermometer = Thermometer.getInstance()
// ...
thermometer
.observeTemperature()
.subscribe { /* ... */ } // Subscribed, but not disposed afterwards!
We subscribed to Thermometer
instance but never released a Disposable resource later. As a result it can blow up an application logic or even cause a memory leak! ?
? Read my post on Medium: Detect Leaked Subscriptions in RxJava code with RxDisposableWatcher ?
Use RxDisposableWatcher plugin to find all undestroyed subscriptions & build the detailed HTML report:
Everything we need: stack trace, number of calls & Observable types.
Getting started
Setup
Gradle:
repositories {
jcenter()
}
implementation 'ru.fomenkov:rx-disposable-watcher:x.y.z'
Maven:
<dependency>
<groupId>ru.fomenkov</groupId>
<artifactId>rx-disposable-watcher</artifactId>
<version>x.y.z</version>
<type>pom</type>
</dependency>
Please replace x.y.z
with the latest version numbers:
Initialization
RxDisposableWatcher.init()
For Android application add storage permission into AndroidManifest.xml
to save & pull generated HTML report:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
⚠️ Note: in case you're facing with IllegalStateException: Plugins can't be changed anymore
, then another application component tries to use RxJavaPlugins utility class with exclusive access. Disable this component when working with the plugin.
Make snapshot & generate HTML report
Now you're ready to go! Check whether you have alive Rx subscriptions at the moment:
val result = RxDisposableWatcher.probe() // Collect info: stacktrace, number of calls, type
val report = HtmlReportBuilder(result).build() // Generate HTML report
For Android save the report to SD card:
val report = ...
val file = File(context.getExternalFilesDir(null), "report.html") // Specify filename
val stream = FileOutputStream(file)
stream.use { it.write(report.toByteArray()) }
Display HTML report in a desktop browser
Pull report file from Android device and display (replace with your paths):
adb pull /sdcard/report.html ~/report.html # Grab a report from SD card
open ~/report.html # for Mac
# or
google-chrome ~/report.html # for Linux
That's it!