@@ -5,6 +5,7 @@ import android.graphics.Bitmap
55import android.view.LayoutInflater
66import android.view.View
77import androidx.lifecycle.Lifecycle
8+ import androidx.lifecycle.LifecycleOwner
89import androidx.lifecycle.coroutineScope
910import com.arcgismaps.ApiKey
1011import com.arcgismaps.ArcGISEnvironment
@@ -40,6 +41,9 @@ import io.flutter.plugin.common.EventChannel
4041import io.flutter.plugin.common.MethodCall
4142import io.flutter.plugin.common.MethodChannel
4243import io.flutter.plugin.platform.PlatformView
44+ import kotlinx.coroutines.CoroutineScope
45+ import kotlinx.coroutines.Dispatchers
46+ import kotlinx.coroutines.SupervisorJob
4347import kotlinx.coroutines.cancel
4448import kotlinx.coroutines.launch
4549import java.io.ByteArrayOutputStream
@@ -57,8 +61,10 @@ internal class ArcgisMapView(
5761 private val viewId : Int ,
5862 private val mapOptions : ArcgisMapOptions ,
5963 private val binding : FlutterPluginBinding ,
60- private val lifecycle : Lifecycle ,
61- ) : PlatformView {
64+ override val lifecycle : Lifecycle ,
65+ ) : PlatformView, LifecycleOwner {
66+
67+ private val coroutineScope = CoroutineScope (Dispatchers .Main .immediate + SupervisorJob ())
6268
6369 private val view: View = LayoutInflater .from(context).inflate(R .layout.vector_map_view, null )
6470 private var mapView: MapView
@@ -97,23 +103,23 @@ internal class ArcgisMapView(
97103
98104 minScale = getMapScale(mapOptions.minZoom)
99105 maxScale = getMapScale(mapOptions.maxZoom)
100- lifecycle. coroutineScope.launch {
106+ coroutineScope.launch {
101107 loadStatus.collect(::onLoadStatusChanged)
102108 }
103109 }
104110
105111 mapView.map = map
106112 mapView.graphicsOverlays.add(defaultGraphicsOverlay)
107113
108- lifecycle. coroutineScope.launch {
114+ coroutineScope.launch {
109115 mapView.mapScale.collect { scale ->
110116 if (scale.isNaN()) return @collect
111117
112118 val zoomLevel = getZoomLevel(mapView)
113119 zoomStreamHandler.addZoom(zoomLevel)
114120 }
115121 }
116- lifecycle. coroutineScope.launch {
122+ coroutineScope.launch {
117123 mapView.viewpointChanged.collect {
118124 // The viewpoint listener is executed async which means that the map
119125 // can be altered when this is called. If we reload the map or dispose the map
@@ -149,7 +155,10 @@ internal class ArcgisMapView(
149155 methodChannel.invokeMethod(" onStatusChanged" , status.jsonValue())
150156 }
151157
152- override fun dispose () {}
158+ override fun dispose () {
159+ coroutineScope.cancel()
160+ mapView.onDestroy(this )
161+ }
153162
154163 // region helper
155164
@@ -220,7 +229,7 @@ internal class ArcgisMapView(
220229 }
221230
222231 private fun onStartLocationDisplayDataSource (result : MethodChannel .Result ) {
223- lifecycle. coroutineScope.launch {
232+ coroutineScope.launch {
224233 mapView.locationDisplay.dataSource.start().onSuccess {
225234 result.success(true )
226235 }.onFailure { e ->
@@ -231,7 +240,7 @@ internal class ArcgisMapView(
231240
232241
233242 private fun onStopLocationDisplayDataSource (result : MethodChannel .Result ) {
234- lifecycle. coroutineScope.launch {
243+ coroutineScope.launch {
235244 mapView.locationDisplay.dataSource.stop().onSuccess {
236245 result.success(true )
237246 }.onFailure { e ->
@@ -280,7 +289,7 @@ internal class ArcgisMapView(
280289 val provider = dataSource.currentProvider as CustomLocationProvider
281290 val optionParams = call.arguments as Map <String , Any >
282291 val position = optionParams.parseToClass<UserPosition >()
283- lifecycle. coroutineScope.launch {
292+ coroutineScope.launch {
284293 provider.updateLocation(position)
285294 result.success(true )
286295 }
@@ -431,7 +440,7 @@ internal class ArcgisMapView(
431440 return
432441 }
433442 val newScale = getMapScale(totalZoomLevel)
434- lifecycle. coroutineScope.launch {
443+ coroutineScope.launch {
435444 mapView.setViewpointScale(newScale).onSuccess {
436445 result.success(true )
437446 }.onFailure { e ->
@@ -456,7 +465,7 @@ internal class ArcgisMapView(
456465 return
457466 }
458467 val newScale = getMapScale(totalZoomLevel)
459- lifecycle. coroutineScope.launch {
468+ coroutineScope.launch {
460469 mapView.setViewpointScale(newScale).onSuccess {
461470 result.success(true )
462471 }.onFailure { e ->
@@ -468,7 +477,7 @@ internal class ArcgisMapView(
468477
469478 private fun onRotate (call : MethodCall , result : MethodChannel .Result ) {
470479 val angleDegrees = call.arguments as Double
471- lifecycle. coroutineScope.launch {
480+ coroutineScope.launch {
472481 mapView.setViewpointRotation(angleDegrees).onSuccess {
473482 result.success(true )
474483 }.onFailure { e ->
@@ -518,7 +527,7 @@ internal class ArcgisMapView(
518527
519528 defaultGraphicsOverlay.graphics.addAll(newGraphic)
520529
521- lifecycle. coroutineScope.launch {
530+ coroutineScope.launch {
522531 updateMap().onSuccess { updateResult ->
523532 result.success(updateResult)
524533 }.onFailure { e ->
@@ -540,7 +549,7 @@ internal class ArcgisMapView(
540549
541550 // Don't use removeAll because this will not trigger a redraw.
542551 graphicsToRemove.forEach(defaultGraphicsOverlay.graphics::remove)
543- lifecycle. coroutineScope.launch {
552+ coroutineScope.launch {
544553 updateMap().onSuccess {
545554 result.success(true )
546555 }.onFailure { e ->
@@ -570,7 +579,7 @@ internal class ArcgisMapView(
570579 }
571580
572581 val initialViewPort = Viewpoint (point.latitude, point.longitude, scale)
573- lifecycle. coroutineScope.launch {
582+ coroutineScope.launch {
574583 mapView.setViewpointAnimated(
575584 initialViewPort,
576585 (animationOptions?.duration?.toFloat() ? : 0F ) / 1000 ,
@@ -603,7 +612,7 @@ internal class ArcgisMapView(
603612 }, SpatialReference .wgs84()
604613 )
605614
606- lifecycle. coroutineScope.launch {
615+ coroutineScope.launch {
607616 val viewpointResult = if (padding != null ) {
608617 mapView.setViewpointGeometry(polyline.extent, padding)
609618 } else {
@@ -633,7 +642,7 @@ internal class ArcgisMapView(
633642 }
634643
635644 private fun onRetryLoad (result : MethodChannel .Result ) {
636- lifecycle. coroutineScope.launch {
645+ coroutineScope.launch {
637646 mapView.map?.retryLoad()?.onSuccess {
638647 result.success(true )
639648 }?.onFailure { e ->
@@ -643,7 +652,7 @@ internal class ArcgisMapView(
643652 }
644653
645654 private fun onExportImage (result : MethodChannel .Result ) {
646- lifecycle. coroutineScope.launch {
655+ coroutineScope.launch {
647656 mapView.exportImage().onSuccess { bitmapResult ->
648657 val bitmap = bitmapResult.bitmap
649658 val stream = ByteArrayOutputStream ()
0 commit comments