Skip to content

Commit b6140c5

Browse files
committed
Update LeakCanary to 2.10
Also added the now required "description" parameter when watching instances. Fixes #580
1 parent b06d260 commit b6140c5

File tree

6 files changed

+41
-34
lines changed

6 files changed

+41
-34
lines changed

android/demos/memory-leaks/src/main/java/com/uber/rib/SampleApplication.java

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@
1616
package com.uber.rib;
1717

1818
import android.app.Application;
19-
import com.squareup.leakcanary.LeakCanary;
20-
import com.squareup.leakcanary.RefWatcher;
2119
import com.uber.rib.core.ActivityDelegate;
2220
import com.uber.rib.core.HasActivityDelegate;
2321
import com.uber.rib.core.RibRefWatcher;
24-
import java.util.concurrent.TimeUnit;
22+
import leakcanary.AppWatcher;
2523

2624
public class SampleApplication extends Application implements HasActivityDelegate {
2725

@@ -31,24 +29,17 @@ public class SampleApplication extends Application implements HasActivityDelegat
3129
public void onCreate() {
3230
activityDelegate = new SampleActivityDelegate();
3331
super.onCreate();
34-
if (!LeakCanary.isInAnalyzerProcess(this)) {
35-
// This process is dedicated to LeakCanary for heap analysis. You should not init your app in
36-
// this process.
37-
installLeakCanary();
38-
}
32+
installLeakCanary();
3933
}
4034

4135
/** Install leak canary for both activities and RIBs. */
4236
private void installLeakCanary() {
43-
final RefWatcher refWatcher =
44-
LeakCanary.refWatcher(this).watchDelay(2, TimeUnit.SECONDS).buildAndInstall();
45-
LeakCanary.install(this);
4637
RibRefWatcher.getInstance()
4738
.setReferenceWatcher(
4839
new RibRefWatcher.ReferenceWatcher() {
4940
@Override
50-
public void watch(Object object) {
51-
refWatcher.watch(object);
41+
public void watch(Object object, String description) {
42+
AppWatcher.INSTANCE.getObjectWatcher().expectWeaklyReachable(object, description);
5243
}
5344

5445
@Override

android/gradle/dependencies.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def external = [
125125
roboelectricBase: "org.robolectric:robolectric:${versions.robolectric}",
126126
rxbinding: 'com.jakewharton.rxbinding2:rxbinding:2.0.0',
127127
rxkotlin: 'io.reactivex.rxjava2:rxkotlin:2.2.0',
128-
leakcanaryDebug: 'com.squareup.leakcanary:leakcanary-android:1.5.4',
128+
leakcanaryDebug: 'com.squareup.leakcanary:leakcanary-android:2.10',
129129

130130
]
131131

android/libraries/rib-base/src/main/kotlin/com/uber/rib/core/RibRefWatcher.kt

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,30 @@ public open class RibRefWatcher {
3434
referenceWatcher = watcher
3535
}
3636

37+
@Deprecated(
38+
"Add the description parameter",
39+
replaceWith = ReplaceWith("watchDeletedObject(objectToWatch, description)"),
40+
)
41+
public open fun watchDeletedObject(
42+
objectToWatch: Any?,
43+
) {
44+
watchDeletedObject(objectToWatch, "missing description")
45+
}
46+
3747
/**
3848
* Watch this object to verify it has no inbound references.
3949
*
4050
* @param objectToWatch the object to watch.
4151
*/
42-
public open fun watchDeletedObject(objectToWatch: Any?) {
52+
public open fun watchDeletedObject(
53+
objectToWatch: Any?,
54+
description: String,
55+
) {
4356
if (objectToWatch == null) {
4457
return
4558
}
4659
if (isLeakCanaryEnabled || uLeakEnabled) {
47-
referenceWatcher?.watch(objectToWatch)
60+
referenceWatcher?.watch(objectToWatch, description)
4861
}
4962
}
5063

@@ -97,7 +110,7 @@ public open class RibRefWatcher {
97110
*
98111
* @param objectToWatch the object to watch.
99112
*/
100-
public fun watch(objectToWatch: Any)
113+
public fun watch(objectToWatch: Any, description: String)
101114

102115
/**
103116
* Method to pipe breadcrumbs into the Breadcrumb logger.

android/libraries/rib-base/src/main/kotlin/com/uber/rib/core/Router.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,10 @@ protected constructor(
141141
public open fun detachChild(childRouter: Router<*>) {
142142
val isChildRemoved = children.remove(childRouter)
143143
val interactor = childRouter.interactor
144-
ribRefWatcher.watchDeletedObject(interactor)
144+
ribRefWatcher.watchDeletedObject(
145+
interactor,
146+
"detached child router ${childRouter.javaClass.name}",
147+
)
145148
ribRefWatcher.logBreadcrumb(
146149
"DETACHED",
147150
childRouter.javaClass.simpleName,

android/libraries/rib-base/src/test/kotlin/com/uber/rib/core/InteractorAndRouterTest.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,13 @@ class InteractorAndRouterTest {
146146
val childInteractor = TestInteractorB()
147147
val childRouter = TestRouterB(childInteractor, component)
148148
router.attachChild(childRouter)
149-
verify(ribRefWatcher, never()).watchDeletedObject(any())
149+
verify(ribRefWatcher, never()).watchDeletedObject(any(), "")
150150

151151
// Action: Detach the child interactor.
152152
router.detachChild(childRouter)
153153

154154
// Verify: the reference watcher observes the detached interactor and child.
155-
verify(ribRefWatcher).watchDeletedObject(eq(childInteractor))
155+
verify(ribRefWatcher).watchDeletedObject(eq(childInteractor), "")
156156
}
157157

158158
@Test
@@ -166,13 +166,13 @@ class InteractorAndRouterTest {
166166
}
167167
val rootRouter = TestRouterB(component, TestInteractorB(), ribRefWatcher)
168168
val child = addTwoNestedChildInteractors()
169-
verify(ribRefWatcher, never()).watchDeletedObject(any())
169+
verify(ribRefWatcher, never()).watchDeletedObject(any(), "")
170170

171171
// Action: Detach all child interactors.
172172
rootRouter.detachChild(child)
173173

174174
// Verify: called four times. Twice for each interactor.
175-
verify(ribRefWatcher, times(2)).watchDeletedObject(any())
175+
verify(ribRefWatcher, times(2)).watchDeletedObject(any(), "")
176176
}
177177

178178
private fun addTwoNestedChildInteractors(): Router<TestInteractorB> {

android/libraries/rib-base/src/test/kotlin/com/uber/rib/core/RibRefWatcherTest.kt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ class RibRefWatcherTest {
3636
fun watchDeletedObject_whenObjectIsNull_shouldDoNothing() {
3737
ribRefWatcher.enableLeakCanary()
3838
ribRefWatcher.setReferenceWatcher(referenceWatcher)
39-
ribRefWatcher.watchDeletedObject(null)
39+
ribRefWatcher.watchDeletedObject(null, "")
4040
verifyNoInteractions(referenceWatcher)
4141
}
4242

4343
@Test
4444
fun watchDeletedObject_whenReferenceWatcherIsNull_shouldDoNothing() {
4545
ribRefWatcher.enableLeakCanary()
46-
ribRefWatcher.watchDeletedObject(Any())
46+
ribRefWatcher.watchDeletedObject(Any(), "")
4747
verifyNoInteractions(referenceWatcher)
4848
}
4949

@@ -52,30 +52,30 @@ class RibRefWatcherTest {
5252
ribRefWatcher.enableLeakCanary()
5353
val obj = Any()
5454
ribRefWatcher.setReferenceWatcher(referenceWatcher)
55-
ribRefWatcher.watchDeletedObject(obj)
56-
verify(referenceWatcher).watch(obj)
55+
ribRefWatcher.watchDeletedObject(obj, "")
56+
verify(referenceWatcher).watch(obj, "")
5757
}
5858

5959
@Test
6060
fun watchDeletedObject_whenNonNullRefWithDisabledLeakCanary_shouldDoNothing() {
6161
val obj = Any()
6262
ribRefWatcher.setReferenceWatcher(referenceWatcher)
63-
ribRefWatcher.watchDeletedObject(obj)
64-
verify(referenceWatcher, never()).watch(obj)
63+
ribRefWatcher.watchDeletedObject(obj, "")
64+
verify(referenceWatcher, never()).watch(obj, "")
6565
}
6666

6767
@Test
6868
fun watchDeletedObject_whenObjectIsNullWithULeak_shouldDoNothing() {
6969
ribRefWatcher.enableULeakLifecycleTracking()
7070
ribRefWatcher.setReferenceWatcher(referenceWatcher)
71-
ribRefWatcher.watchDeletedObject(null)
71+
ribRefWatcher.watchDeletedObject(null, "")
7272
verifyNoInteractions(referenceWatcher)
7373
}
7474

7575
@Test
7676
fun watchDeletedObject_whenReferenceWatcherIsNullULeakEnabled_shouldDoNothing() {
7777
ribRefWatcher.enableULeakLifecycleTracking()
78-
ribRefWatcher.watchDeletedObject(Any())
78+
ribRefWatcher.watchDeletedObject(Any(), "")
7979
verifyNoInteractions(referenceWatcher)
8080
}
8181

@@ -84,15 +84,15 @@ class RibRefWatcherTest {
8484
ribRefWatcher.enableULeakLifecycleTracking()
8585
val obj = Any()
8686
ribRefWatcher.setReferenceWatcher(referenceWatcher)
87-
ribRefWatcher.watchDeletedObject(obj)
88-
verify(referenceWatcher).watch(obj)
87+
ribRefWatcher.watchDeletedObject(obj, "")
88+
verify(referenceWatcher).watch(obj, "")
8989
}
9090

9191
@Test
9292
fun watchDeletedObject_whenNonNullRefULeakDisabled_shouldDoNothing() {
9393
val obj = Any()
9494
ribRefWatcher.setReferenceWatcher(referenceWatcher)
95-
ribRefWatcher.watchDeletedObject(obj)
96-
verify(referenceWatcher, never()).watch(obj)
95+
ribRefWatcher.watchDeletedObject(obj, "")
96+
verify(referenceWatcher, never()).watch(obj, "")
9797
}
9898
}

0 commit comments

Comments
 (0)