@@ -126,14 +126,15 @@ private boolean isMaskingEnabled() {
126126 if (isMaskingEnabled ()) {
127127 final @ Nullable ViewHierarchyNode rootNode = captureViewHierarchy (activity );
128128 if (rootNode == null ) {
129- // Don't return unmasked screenshot when masking is configured
129+ screenshot . recycle ();
130130 return event ;
131131 }
132- screenshot = applyMasking (screenshot , rootNode );
133- if (screenshot == null ) {
134- // Don't return unmasked screenshot when masking is configured
132+ final @ Nullable Bitmap masked = applyMasking (screenshot , rootNode );
133+ if (masked == null ) {
134+ // applyMasking already recycles its bitmaps on failure
135135 return event ;
136136 }
137+ screenshot = masked ;
137138 }
138139
139140 final Bitmap finalScreenshot = screenshot ;
@@ -210,6 +211,7 @@ private boolean isMaskingEnabled() {
210211 if (!screenshot .isMutable ()) {
211212 mutableBitmap = screenshot .copy (Bitmap .Config .ARGB_8888 , true );
212213 if (mutableBitmap == null ) {
214+ screenshot .recycle ();
213215 return null ;
214216 }
215217 createdCopy = true ;
@@ -225,11 +227,14 @@ private boolean isMaskingEnabled() {
225227 return mutableBitmap ;
226228 } catch (Throwable e ) {
227229 options .getLogger ().log (SentryLevel .ERROR , "Failed to mask screenshot" , e );
228- // Recycle the copy if we created one, to avoid memory leak
229- if (createdCopy && !mutableBitmap .isRecycled ()) {
230- mutableBitmap .recycle ();
230+ if (createdCopy ) {
231+ if (!mutableBitmap .isRecycled ()) {
232+ mutableBitmap .recycle ();
233+ }
234+ }
235+ if (!screenshot .isRecycled ()) {
236+ screenshot .recycle ();
231237 }
232- // Don't return unmasked screenshot when masking is configured
233238 return null ;
234239 }
235240 }
0 commit comments