Compose, lifecycle and object already owned

962
3
Jump to solution
09-20-2023 12:27 AM
padmalcom
Frequent Contributor

Hi, we use ArcGISMap in an AndroidView. When we recompose the composition so that the map is not rendered anymore and recompose again  so that the map is displayed again, I get the common error "object already owned" for the wmts map we assign to the ArcGISMap. I understand that.

What I do to avoid that is to use the onRelease callback from the AndroidView to set the map to null.

onRelease = { view ->
// Required, if not set to null, map object will be marked
// as owned when retuning from zoom view
view.map = null
}

This works for the recomposition part. But when I finish() the Activity, I get the following error in 50% of my tests. This seems to me like the map may not be null.

java.lang.RuntimeException: Unable to destroy activity {de.bwi.kvib.mobile.dev/de.bwi.kvib.mobile.feature.pois.PoiComposeActivity}: java.lang.NullPointerException: Null pointer.

...

Caused by: java.lang.NullPointerException: Null pointer.

...

Caused by: com.arcgismaps.exceptions.ArcGISExceptionImpl: message=Null pointer., additionalMessage=object cannot be null., errorCode=1

Can you propose a solution to either avoid that NPE or unassign the map from the ArcGISMap?

0 Kudos
1 Solution

Accepted Solutions
SorenRoth
Esri Contributor

Hi, we have a reference implementation of using the MapView in an AndroidView you can refer to here 

In this reference you will see two things that ensure proper internal management of the MapView and its reference to the ArcGISMap.

1) Your activity should be registered as a LIfecycleObserver, and in your composable yo can get a handle to the LIfecycleOwner by calling 

 

 

val lifecycleOwner = LocalLifecycleOwner.current

 

 

2) Once you have this lifecycleOwner, you can set up a DisposableEffect to run when the AndroidView leaves the composition, and properly disposes the MapView.

 

 

DisposableEffect(Unit) {
    onDispose {
        mapView.onDestroy(lifecycleOwner)
    }
}

 

 

 

This will do several things internally to gracefully release resources, including setting the map to null.

 

View solution in original post

3 Replies
SorenRoth
Esri Contributor

Hi, we have a reference implementation of using the MapView in an AndroidView you can refer to here 

In this reference you will see two things that ensure proper internal management of the MapView and its reference to the ArcGISMap.

1) Your activity should be registered as a LIfecycleObserver, and in your composable yo can get a handle to the LIfecycleOwner by calling 

 

 

val lifecycleOwner = LocalLifecycleOwner.current

 

 

2) Once you have this lifecycleOwner, you can set up a DisposableEffect to run when the AndroidView leaves the composition, and properly disposes the MapView.

 

 

DisposableEffect(Unit) {
    onDispose {
        mapView.onDestroy(lifecycleOwner)
    }
}

 

 

 

This will do several things internally to gracefully release resources, including setting the map to null.

 

padmalcom
Frequent Contributor

Hi Soren, thank you for the  fast reply. The example is what I was looking for.

0 Kudos
LeighWoolley
Emerging Contributor

Had this problem too with Scenes, the sample apps in arcgis-maps-sdk-kotlin-samples are missing:

mapView.onDestroy(lifecycleOwner) or sceneView.onDestroy(lifecycleOwner) view calls. 

It only appeared to matter once I changed the viewmodels to hiltViewModels.

 

0 Kudos