11import  'dart:async' ;
22import  'dart:typed_data' ;
33
4+ import  'package:ffi/ffi.dart' ;
45import  'package:jni/jni.dart' ;
56import  'package:meta/meta.dart' ;
67
@@ -245,21 +246,18 @@ class SentryNativeJava extends SentryNativeChannel {
245246
246247  @override 
247248  void  addBreadcrumb (Breadcrumb  breadcrumb) {
248-     native .Breadcrumb ?  nativeBreadcrumb;
249-     JObject ?  nativeOptions;
250- 
251249    tryCatchSync ('addBreadcrumb' , () {
252-       nativeOptions  =   native . ScopesAdapter . getInstance () ? . getOptions (); 
253-       if  ( nativeOptions ==    null )  return ; 
254- 
255-       nativeBreadcrumb  =   native . Breadcrumb . fromMap ( 
256-            _dartToJMap (breadcrumb. toJson ()), nativeOptions ! ); 
257-       if  (nativeBreadcrumb  ==   null )  return ;
258- 
259-       native . Sentry . addBreadcrumb$1 (nativeBreadcrumb ! );
260-     }, finallyFn :  () { 
261-       nativeOptions ? . release ( );
262-       nativeBreadcrumb ? . release ( );
250+       using ((arena) { 
251+          final   nativeOptions =   native . ScopesAdapter . getInstance () ? . getOptions () 
252+            ? .. releasedBy (arena); 
253+          if  (nativeOptions  ==   null )  return ; 
254+         // Wrap the entire conversion in arena to auto-cleanup all JObjects 
255+          final  jMap  =   _dartToJMap (breadcrumb. toJson (), arena) ;
256+          final  nativeBreadcrumb  =   native . Breadcrumb . fromMap (jMap, nativeOptions) 
257+            ? .. releasedBy (arena );
258+          if  (nativeBreadcrumb  ==   null )  return ; 
259+          native . Sentry . addBreadcrumb$1 (nativeBreadcrumb );
260+       } );
263261    });
264262  }
265263
@@ -269,27 +267,36 @@ class SentryNativeJava extends SentryNativeChannel {
269267      });
270268}
271269
272- JObject ?  _dartToJObject (Object ?  value) =>  switch  (value) {
270+ JObject ?  _dartToJObject (Object ?  value,  Arena  arena ) =>  switch  (value) {
273271      null  =>  null ,
274-       String  s =>  s.toJString (),
275-       bool  b =>  b.toJBoolean (),
276-       int  i =>  i.toJLong (),  // safer for 64-bit 
277-       double  d =>  d.toJDouble (),
278-       List <dynamic > l =>  _dartToJList (l),
279-       Map <String , dynamic > m =>  _dartToJMap (m),
272+       String  s =>  s.toJString ().. releasedBy (arena) ,
273+       bool  b =>  b.toJBoolean ().. releasedBy (arena) ,
274+       int  i =>  i.toJLong ().. releasedBy (arena), 
275+       double  d =>  d.toJDouble ().. releasedBy (arena) ,
276+       List <dynamic > l =>  _dartToJList (l, arena ),
277+       Map <String , dynamic > m =>  _dartToJMap (m, arena ),
280278      _ =>  null 
281279    };
282280
283- JList <JObject ?> _dartToJList (List <dynamic > values) {
284-   final  jlist =  JList .array (JObject .nullableType);
285-   jlist.addAll (values.map (_dartToJObject));
281+ JList <JObject ?> _dartToJList (List <dynamic > values, Arena  arena) {
282+   final  jlist =  JList .array (JObject .nullableType)..releasedBy (arena);
283+ 
284+   for  (final  value in  values) {
285+     final  jObj =  _dartToJObject (value, arena);
286+     jlist.add (jObj);
287+   }
288+ 
286289  return  jlist;
287290}
288291
289- JMap <JString , JObject ?> _dartToJMap (Map <String , dynamic > json) {
290-   final  jmap =  JMap .hash (JString .type, JObject .nullableType);
292+ JMap <JString , JObject ?> _dartToJMap (Map <String , dynamic > json, Arena  arena) {
293+   final  jmap =  JMap .hash (JString .type, JObject .nullableType)..releasedBy (arena);
294+ 
291295  for  (final  entry in  json.entries) {
292-     jmap[entry.key.toJString ()] =  _dartToJObject (entry.value);
296+     final  key =  entry.key.toJString ()..releasedBy (arena);
297+     final  value =  _dartToJObject (entry.value, arena);
298+     jmap[key] =  value;
293299  }
300+ 
294301  return  jmap;
295302}
0 commit comments